Jump to content
Search Community

Understanding autoAlpha

venn test
Moderator Tag

Go to solution Solved by OSUblake,

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

Hi team,

 

I am trying to use GSAP with Framer.js API.

 

So as usual Framer will import all my Sketch designs into the workflow.

If my layer is (eg: ABC) in Sketch, I will be able to target it with

TweenMax.to(ABC, 1, {opacity: 0});

However, I won't be able to use autoAlpha with this.

TweenMax.to(ABC, 1, {autoAlpha: 0}); <-- Not working

I know this might be some Framer thing.

However I would like to know how autoAlpha works behind the hood so maybe I can fix it to get GSAP work with Framer.

 

Does autoAlpha makes an element opacity:0 and visibility:hidden when autoAlpha:0 ? Any other things else?

 

  • Like 1
Link to comment
Share on other sites

Hello venn

 

Say your  element is already visible. Basically autoAlpha will animate opacity from 1 to 0 then set the visibility property to hidden. When you animate autoAlpha to 0. autoAlpha will set visibility hidden to visible then animate opacity from 0 to 1 (or whatever value you set it to.)

 

You could try this, and see if GSAP will set visibility:hidden after animating opacity to 0.

TweenMax.to(ABC, 1, {opacity: 0, visibility:"hidden"});

autoAlpha is part of the CSSPlugin:

 

http://greensock.com/docs/#/HTML5/GSAP/Plugins/CSSPlugin/

  • autoAlpha
    Identical to opacity except that when the value hits 0 the visibility property will be set to "hidden" in order to improve browser rendering performance and prevent clicks/interactivity on the target. When the value is anything other than 0, visibility will be set to "inherit". It is not set to "visible" in order to honor inheritance (imagine the parent element is hidden - setting the child to visible explicitly would cause it to appear when that's probably not what was intended). And for convenience, if the element's visibility is initially set to "hidden" and opacity is 1, it will assume opacity should also start at 0. This makes it simple to start things out on your page as invisible (set your css visibility:hidden) and then fade them in whenever you want.

If you are still having an issue. Then please setup a limited codepen showing the issue so we can test your code live. to find out what is going on.

 

 

Thanks!

  • Like 4
Link to comment
Share on other sites

Thanks Jonathan.

 

I tried: 

TweenMax.to(ABC, 1, {opacity: 0, visibility:"hidden"});

However it is immediately set to hidden instead of tweening to opacity 0 first?

 

I will try to create a Framer.js codepen to demonstrate my problem.

Link to comment
Share on other sites

Here you go, this is the codepen

 

See the Pen BQBYeL by vennsoh (@vennsoh) on CodePen

 

As you can see, 

 

// Autoalpha (This will not work)
TweenMax.to(yolo, 3, {autoAlpha: 0, repeat: -1});
 
// Autoalpha (This will work)
TweenMax.to(yolo, 3, {x: 500, repeat: -1});
 
// Autoalpha (This will work)
TweenMax.to(testVar, 3, {autoAlpha: 0, repeat: -1});
 
According to Framer, I need to create a variable that query the HTML in a Framer layer in order to get a reference to a DOM.
 

If you need to target any of the created elements, remember that they are only available after Framer rendered them. To reliably get a reference to a DOM element, use layer.querySelector or layer.querySelectorAll

---

 

It seems that I can only target the HTML elements but not the Framer layers? However Framer layers are essentially a HTML <div> element. I am not sure why I can't target it. I am suspecting this is how Framer renders it. Maybe it is not available when GSAP is trying to perform some actions on it or some other Framer thing is overwriting GSAP stuff.

Link to comment
Share on other sites

Thanks for the demo. Very helpful, especially because i have no experience with Framer.

 

The following tween will work:

TweenMax.to(yolo, 3, {x: 500, repeat: -1});

Because a Framer layer actually has an x property

 

 

 

f8f0f36ddb1245bcbe2aafcd60719288.png

So when you tween yolo.x Framer knows to get involved and update the position of the <div> that is used to render that layer on screen.

 

 

Your yolo layer does not have an autoAlpha property. AutoAlpha is only for tweens where the target is a DOM element because autoAlpha has to adjust the CSS opacity and visibility. This explains why querying the div that the yolo layer uses was necessary for the autoAlpha tween to work. 

 

testVar = yolo.querySelector("#test");
TweenMax.to(testVar, 3, {autoAlpha: 0, repeat: -1});

 

 

Does that clear things up?

  • Like 3
Link to comment
Share on other sites

Good catch Carl,

 

I passed visibility: 'hidden' inside the yolo new Layer object and Framer.js wont apply it.

I even tried to set visibility: 'hidden' on the target of yolo via

  • native vanilla JS using element.style.visibility
  • jQuery css() method
  • and in the onComplete of the to() tween using the set() method

But it looks like FramerJS will not apply the CSS visibility property on the inline style.

 

It does apply opacity but the not the CSS visibility property.

  • Like 1
Link to comment
Share on other sites

Thanks Carl and Jonathan for being so helpful!

 

Yes, I am much aware that:

testVar = yolo.querySelector("#test");
TweenMax.to(testVar, 3, {autoAlpha: 0, repeat: -1});

Will work.

 

But my problem here is essentially what Jonathan has demonstrated.

I would like to target the Framer layer itself (yolo) not the html layer (#test) that is created insider a Framer layer.

 

My assumption is that a Framer layer is just a normal div layer so I am not sure why autoAlpha will not work on it. Maybe there is more to it.

As Jonathan mentioned, I can apply opacity to a Framer layer but I can't control the visibility property of it. There is something with Framer.js that is overriding or supersede it. Lol.

 

Framer has a .visible property but that will just set display: none instead of visibility: hidden.

 

-

 

I tried to use GSAP to add a CSS class to it:

.invi{
  visibility: hidden;
}

TweenMax.to(yolo, 3, {className: "invi"}); <-- Will not work

But it is not working too.

 

I can only use the Framer api to add CSS class:

yolo.classList.add("invi") <-- Will work

I am even thinking if GSAP can tween Framer API, something absurb like

TweenMax.to(yolo, 3, {yolo.classList.add: "invi"}); <-- Will not work

https://framerjs.com/docs/#layer.classList

 

 

In the past, I have tried tweening Framer API using GSAP and it works.

TweenMax.to(yolo, 3, {blur:20}); <-- Will work 

https://framerjs.com/docs/#layer.blur

 

---

 

So I am guessing a layer created in Framer has something going on.

Link to comment
Share on other sites

  • Solution

I know I brought up creating a plugin before...

http://greensock.com/forums/topic/15101-tweening-other-libraries-api/

 

I understand that might be difficult, so lets do the next best thing, use getters and setters.

 

Here is a related pen I just showed @Dipscom about different ways to use gettters/setters with GSAP.

See the Pen 6d42dd35adee8af8ce9c1bcf3f2e6cb2?editors=0010 by osublake (@osublake) on CodePen

 

So let's examine an object. If you log one out to your console, it will show you all the properties and methods associated with it.

console.log("YOLO", yolo);

When you see a property followed by ellipsis (...), that is a getter/setter. Clicking on the ellipsis will access (getter) the object and retrieve the value. If you were to set the property, it will run the setter function, and do some stuff to update your object.

 

So lets create an autoAlpha getter/setter for a framer layer. For this we can use the opacity property and the visible property. The visible property is a boolean in Framer, which sets display to none. That's not exactly how GSAP's autoAlpha works, but this is just an example.

 

So for the getter, it will return the opacity. And for the setter, it will set the visible property to true/false based on the value passed in, and also set the opacity.

 

And here it is in action...

See the Pen xRxdpW?editors=0010 by osublake (@osublake) on CodePen

 

.

  • Like 3
Link to comment
Share on other sites

Thanks Blake! That's some next level Javascript there.

 

I am trying to convert what you have done to ES6 instead. Is there a way? 

Or is what you have suggested the best way? 


  get x() { return this.opacity; }
  set x(value) {
    this.visible = !!value;
    this.opacity = value;
    }

and is this necessary?

enumerable: true,
configurable: true

The code seems to be working alright without them?

 

And I notice you use this?

var log = console.log.bind(console);

What's that sorcery?

--- 

 

Another easy but can prove to be challenging and less robust in the future way:

TweenMax.to(haha, 3, {opacity: 0, onComplete: done});

function done(){
this.target.visible = false;
}
Link to comment
Share on other sites

Enumerable and configurable are optional, but are usually included for what I did. You can read about what they do here.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

 

For existing classes, like the Framer's Layer class, you kind of have to use that Object.defineProperty syntax. However, you can extend the Layer class using ES6, creating an entirely brand new class.

 

class GSAPLayer extends Layer {  
  constructor(config) {
    super(config);
  }
  
  get autoAlpha() { return this.opacity; }
  set autoAlpha(value) {
    this.visible = !!value;
    this.opacity = value;
  }
}
 

Now you have a new Layer class that you can add whatever to, like your own special GSAP properties, and you would use it the same way.

 

var yolo = new GSAPLayer({
  width: Screen.width,
  height: 1000,
  backgroundColor: 'red',
  html: "<div id='test'>hahaha</div>"
});
 

See the Pen yVLpRL?editors=0010 by osublake (@osublake) on CodePen

.

  • Like 1
Link to comment
Share on other sites

Another easy but can prove to be challenging and less robust in the future way:

TweenMax.to(haha, 3, {opacity: 0, onComplete: done});

function done(){
this.target.visible = false;
}

 

 

Yep, but that could get tricky because you also have to make sure visible isn't set to false if you want to tween its opacity back.

 

 

So for this...

var log = console.log.bind(console);

Well... actually, it looks like you don't have to do that in CodePen in anymore. You can just call log("foo") directly now, but it's just a shorthand way to call console.log. Normally if you don't bind console, you'll get a scope error, and bind sets the correct scope.

 

Behind the scenes, bind works just like .call() or .apply(), but returns a new function. See if you can make sense of this...

See the Pen 05f4caed3760fbcf0d035debee476dc7?editors=0010 by osublake (@osublake) on CodePen

 

 

.

  • Like 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.
×
×
  • Create New...