mikel

Using scope -solved

Recommended Posts

Hi @mikel

 

You only need to worry about scope if the function uses "this" inside it. What you want is to pass a parameter to the function like this.

TweenMax.to(action,1,{scale:0.2, onComplete:goToSlide, onCompleteParams: [$currentSlide.next()] })

 

  • Thanks 1

Share this post


Link to post
Share on other sites

I did notice that the goToSlide function does use "this" inside it.

TweenLite.to($slidesContainer, 1, {
  scrollTo: {
    y: pageHeight * $currentSlide.index() 
  }, 
  onComplete: onSlideChangeEnd, 
  onCompleteScope: this // <= this???
});

 

But that's probably redundant because the function it's calling, onSlideChangeEnd, doesn't use "this". 

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

In short, scope is the object that "this" refers to in a function. By default, the scope of a callback in a tween/timeline is the tween/timeline itself. With jQuery, most methods have the scope set to the element, which is what "this" refers to in the function.

$("button").click(function() {
  TweenLite.to(this, 1, { color: "red" });
});

 

See if you can make sense of the scope here.

 

 

  • Like 3

Share this post


Link to post
Share on other sites

Hi @OSUblake,

 

Thanks for the hint and the lessons.

 

For mousewheel, button and key it is now ok.

 

 

Kind regards

Mikel

  • Like 1

Share this post


Link to post
Share on other sites

It's a pity, that TimelineLite doesn't respect function scope in .add() method.

For example, if I create bound function and pass it to the Timeline, the scope changes to the timeline's:

 

f = someFunction.bind(someScope);

timeline.add(f);

 

.add() could check if a scope is already set as a function property and pass it further? like:

 

someFunction.scope = someScope;

timeline.add(someFunction);

 

It could work, why not 8)

 

 

Share this post


Link to post
Share on other sites

What are you talking about? You can't change the scope of a bound function.

  • Like 1

Share this post


Link to post
Share on other sites
18 hours ago, OSUblake said:

What are you talking about? You can't the scope of a bound function.

 

I cant run my function with selected scope if I use TimelineLite .add() method. It (the .add() method at GSAP) could be modified to check if that function had .scope property and pass it further.. that's what I meant.

 

It's a one-line change. In GSAP source code, it does:

 

...
				} else if (typeof(value) === "function") {
					value = TweenLite.delayedCall(0, value);
				} else {
...

 

and could be:

...
				} else if (typeof(value) === "function") {
					value = TweenLite.delayedCall(0, value, value.params, value.scope);
				} else {
...

 

 

Share this post


Link to post
Share on other sites

@determin1st I'm confused. Do you have an example of it not working properly? Like maybe a super simple codepen? I'm not seeing any odd behavior but maybe I'm missing something.

  • Like 1

Share this post


Link to post
Share on other sites

Jumping on the bandwagon!

 

If the mighty @GreenSock is confused, what do you think will happen to us mortals? Brain melts and generalised panic.

 

On a side note, you can bind scope and add in a timeline...

 

 

As the man himself has said, a simple pen showcasing your issue will greatly help.

  • Like 1

Share this post


Link to post
Share on other sites
21 minutes ago, GreenSock said:

@determin1st I'm confused. Do you have an example of it not working properly? Like maybe a super simple codepen? I'm not seeing any odd behavior but maybe I'm missing something.

 

It's not odd. It (the .add() method) just dont allows to pass function scope. In my work I have a pre-defined objects with data like:

show: [
  {
    duration: 0,
    tween: {
      visibility: 'visible',
      scale: 0
    }
  }, {
    duration: 0.8,
    tween: {
      scale: 1,
      ease: Back.easeOut
    }
  }, function(){
    debugger;
    this.cfg.data.menu.addClass('attached');
  }
],

 

 

then, in another place, I create timeline using that data:

 

c = new TimelineLite({
  paused: true
});
this.cfg.show && this.cfg.show.forEach(function(a){
  var b;
  if (a.tween) {
    b = w3ui.CLONE(a.tween);// have to clone, because GSAP modifies original :|
    c.to(node, a.duration, b);
  } else {
    c.add(a);// bound functions dont work here
  }
});

 

 

 

Share this post


Link to post
Share on other sites

I 'a' is an already bound function, I see no reason why it wouldn't work. I have in the past had to create a variable to hold the binding before adding to an event listerner, for example, in order to preserve the bind when accessing it from another place. It could be that you might have to do something similar.

 

// Sorry if this isn't too clear, trying to remember without going after some sample code
var a = function() {}
var b = a.bind(c)

var obj {
	d: b
}

timeline.add(obj.d)

 

  • Like 2

Share this post


Link to post
Share on other sites
10 minutes ago, Dipscom said:

I 'a' is an already bound function, I see no reason why it wouldn't work. I have in the past had to create a variable to hold the binding before adding to an event listerner, for example, in order to preserve the bind when accessing it from another place. It could be that you might have to do something similar.

 

 

ops. i had an error in my code. improper init. it (bound function) works, thank you.

  • Like 1

Share this post


Link to post
Share on other sites
9 minutes ago, determin1st said:

 

ops. i had an error in my code. improper init. it (bound function) works, thank you.

 

Damn semicolons; we should burn them all at the stake. 

  • Like 2

Share this post


Link to post
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.