greensock / GSAP

GSAP (GreenSock Animation Platform), a JavaScript animation library for the modern web
https://gsap.com
19.71k stars 1.73k forks source link

"{self}" variable #507

Closed erhanbaris closed 2 years ago

erhanbaris commented 2 years ago

Hi, When I check the changelog, I figure out that "{self}" has been removed. But I need to access the current Tween. Any idea to access running tween data? Here is my example code.

        .to(itemx, {
            pixi: { x, y },
            onStart:(self, item) => {
                if (item.number == 1) self.progress(1);
            },
            onStartParams: ["{self}", itemx]
        })
        .to(itemy, {
            pixi: { x, y },
            onStart:(self, item) => {
                if (item.number == 1) self.progress(1);
            },
            onStartParams: ["{self}", itemy]
        })

Node: itemx, itemy etc. etc. are dynamically added and location can be updated so I don't want to execute that tween anymore.

jackdoyle commented 2 years ago

Yeah, "{self}" is no longer needed because the function is scoped to the tween instance by default, so you can just use "this" in a regular (NOT arrow) function:

.to(itemx, {
  pixi: {x, y}, 
  onStart: function() {
    itemx.number === 1 && this.progress(1);
  }
})
jonlepage commented 2 years ago

Yeah, "{self}" is no longer needed because the function is scoped to the tween instance by default, so you can just use "this" in a regular (NOT arrow) function:

.to(itemx, {
  pixi: {x, y}, 
  onStart: function() {
    itemx.number === 1 && this.progress(1);
  }
})

am not sure i understand this desition me too . How should we access to tween in this case ?

class A {

    container: DisplayObject;
    _flag = false;

    doAnime(){
        gsap.to( this.container.position, {
            x:0,
            y:0,
            onStart: () => {
                // how acces tween ? 
                this._flag = true;
            },
        } );
    }

}
jackdoyle commented 2 years ago

That's why I said NOT arrow functions because those handle scope differently (that's a JavaScript thing, not a GSAP thing). Just switch to a normal function and then "this" will refer to the tween instance.

If you're having trouble still, please provide a minimal demo in CodePen or something like that and we'd be happy to take a peek.

jackdoyle commented 2 years ago

And to answer your other question, just use a variable...

class A {

    container: DisplayObject;
    _flag = false;

    doAnime(){
        let self = this;
        gsap.to( this.container.position, {
            x:0,
            y:0,
            onStart: function() {
                self._flag = true;
                console.log("tween:", this, "class instance:", self);
            },
        } );
    }

}

Or the other way around:

class A {

    container: DisplayObject;
    _flag = false;

    doAnime(){
        let tween = gsap.to( this.container.position, {
            x:0,
            y:0,
            onStart: () => {
                this._flag = true;
                console.log("tween:", tween, "class instance:", this);
            },
        } );
    }

}
jonlepage commented 2 years ago

And to answer your other question, just use a variable...

Or the other way around:

Sure but this force to pollute the code at a higher level. Ideally, the use of a Library aims to make as much abstraction as possible of this kind of code (scopings,declarations..). I guess you probably have your reasons for make this change and promo this practice?

If you're worried about performance, be aware that v8 and probably every other web engine has performance fixes related to monomorphic and polymorphic params today. https://www.diva-portal.org/smash/get/diva2:1626575/FULLTEXT01.pdf

Passing parameters no longer impacts performance (~since 2012) image

And it allows the user to extract what they want to use via the arguments, rather than polluting the exploiting code. I will be curious in knowing more about this idea or what make you preferer of having pure functions without parameters?

jackdoyle commented 2 years ago

I'm not sure why you think it's "polluting" things at a higher level. I actually think it's a much cleaner solution because:

Performance was not a factor in the decision.

Does that clear things up?

jonlepage commented 2 years ago

No "magic" variables (I think most people would look at "{self}" and wonder what in the world that is)

name are not strict in signature, you extract if you need, and use arrow or bind if you need scope ctx. The tween context should shared in params and not binded to cb.

gsap.to( obj, { onStart: (tweenContext,...restParam) => {  } } );

It allows us to reduce the file size (and API surface area) of GSAP slightly

i am not sure if this is a joke. we may talk about ~100byte

It's simpler and more consistent with standard JavaScript practices

we dont have same view of modern standard events pattern.

Does that clear things up?

yes thanks, we definitively dont share same view on this part. thank you for your time and shared your points.