Jump to content
Search Community

Some questions about the apple airpods animation.

eddiedev test
Moderator Tag

Go to solution Solved by akapowl,

Recommended Posts

Hello fellow developers,

I started looking into the ScrollTrigger plugin as it seems very interesting, and while looking on the GSAP's codepen profile for different project ideas, I found this nice airpods animation. After looking into the code I figured out how 80% of it works but I still have some questions.

Firstly, how does the "airpods" variable work? It obviously increments after each frame but I don't seem to find out where exactly it does that. Also, it uses the function gsap.to(airpods, {....}) which doesn't make much sense as "airpods" doesn't look like a proper html element. Fruthermore, I can't figure out why Inside the gsap.to function there is "frame: frameCount - 1", as the "frame" property doesn't appear on the docs at all.

Secondly (this is more of a curiosity of mine), on the official apple website it also presents some features of the airpods while running the scroll triggered animation on the background. I was just wondering how would that be possible given the fact that the animation on the codepen acts like a fixed html canvas, so it would be a pain to display any other kind of media on the website.

Thanks for reading all the way, even though some questions might not make any sense at all. Any help is appreciated.

See the Pen ZEaZyZr by GreenSock (@GreenSock) on CodePen

Link to comment
Share on other sites

  • Solution

 

Welcome to the GreenSock forums @eddiedev

 

1 hour ago, eddiedev said:

Firstly, how does the "airpods" variable work? It obviously increments after each frame but I don't seem to find out where exactly it does that. Also, it uses the function gsap.to(airpods, {....}) which doesn't make much sense as "airpods" doesn't look like a proper html element. Fruthermore, I can't figure out why Inside the gsap.to function there is "frame: frameCount - 1", as the "frame" property doesn't appear on the docs at all.

 

While GSAP certainly is most widely used to tween on existing HTML elements' values, it can tween on just about any value you feed it with and what you do with that value being tweened on in the end is up to you. That is what's happening in that example in the .to() tween.

 

First the object airpods is created with the key frame and its value set to 0.   

 

let airpods = {
  frame: 0
};

 

Then in the .to() tween

 

gsap.to(airpods, {
  frame: frameCount - 1,
  snap: "frame",
  ease: "none",
  scrollTrigger: {
    scrub: 0.5
  },
  onUpdate: render // use animation onUpdate instead of scrollTrigger's onUpdate
});

 

on the target airpods (the object), gsap can access that key since it was created beforehand.

 

let frameCount = 147;

 

The framecount - 1 tells it to tween to the value of that variable that was created beforehand minus 1 because while there is a number of 147 frames, the array of images spans from index 0 ( index of first frame ) to index 146 ( index of last frame) - that's just how arrays work.

 

Now so far GSAP is only interpolating that value of frame between 0 and 146 and nothing visual is actually happening. That is what the function in the onUpdate callback of that tween is handling then. It takes the value that this interpolation is at while updating the tween and renders out the frame with the number corresponding to the process of the interpolation of the value accordingly.

 

Here is an exmample that is a bit more reduced - which uses the same basis. Only difference is it doesn't render out an image while updating but sets the textContent of an HTML element to what the value is at. As you see, as long as you stick to certain JS logic, it doesn't matter much what the names are. As it is a 100% custom object that is created before the tween, that is why you won't find that property in the docs.

 

See the Pen ZEvxRWJ by akapowl (@akapowl) on CodePen

 

 

 

1 hour ago, eddiedev said:

Secondly (this is more of a curiosity of mine), on the official apple website it also presents some features of the airpods while running the scroll triggered animation on the background. I was just wondering how would that be possible given the fact that the animation on the codepen acts like a fixed html canvas, so it would be a pain to display any other kind of media on the website.

Thanks for reading all the way, even though some questions might not make any sense at all. Any help is appreciated.

 

It doesn't need to be fixed though and you can still display other content on top of it (on the z-axis that is). It can be positioned relative in the flow of the page (the surrounding container that is), and when you need it to, you could pin the canvas itself via ScrollTrigger, while the other content in that surrounding container keeps scrolling.

 

See the Pen jOYzpxe by akapowl (@akapowl) on CodePen

 

 

 

There is a very popular thread (probably one of the most popular on ScrollTrigger) with regard to that codepen demo, which contains a lot of additional questions and shows how to do certain things within that context. I would suggest diving in and reading through it - it will surely help. But if you are not very familiar with ScrollTrigger altogether so far, maybe it would help to get your feet wet with some less complex cases first.

 

Nonetheless, I hope this helps understand things a bit better.

 

 

  • Like 4
Link to comment
Share on other sites

  • 1 year later...
  • 1 month later...
On 27/10/2023 at 12:36, GreenSock said:

Volviendo atrás para compartir una pequeña función auxiliar que podría hacer que esto sea más fácil de implementar para la gente: 

 

 

I have been trying to make these types of examples work in react for quite some time, since the structure is somewhat different, however I can't get any examples, I have tried to do it in several ways and nothing I can do, maybe to import the images directly I think that It is not compatible, maybe if someone can guide me more how to replicate this in react

Link to comment
Share on other sites

47 minutes ago, marceloxf said:

I have been trying to make these types of examples work in react for quite some time, since the structure is somewhat different, however I can't get any examples, I have tried to do it in several ways and nothing I can do, maybe to import the images directly I think that It is not compatible, maybe if someone can guide me more how to replicate this in react

I had a similar question, and Jack posted this on my thread, which helped a lot:

 

https://stackblitz.com/edit/react-6u8izj?file=src%2FApp.js

  • Like 1
Link to comment
Share on other sites

14 hours ago, newguy123 said:

So this takes care of the useLayoutEffect and also the cleanup for you it seems?

That's exactly right. It's just a simple wrapper that does that stuff for you so that you can write less code. It might help to read through the explanation here: 

https://www.npmjs.com/package/@gsap/react

 

Benefits: 

  • Automatically handles cleanup using gsap.context()
  • Implements useIsomorphicLayoutEffect() technique, preferring React's useLayoutEffect() but falling back to useEffect() if window isn't defined, making it safe to use in server-side rendering environments.
  • Optionally define a scope for selector text, making it safer/easier to write code that doesn't require you to create a useRef() for each and every element you want to animate.
  • Defaults to using an empty dependency Array in its simplest form, like useGSAP(() => {...}) It was common for developers to forget to include that on React's useLayoutEffect(() => {...}, []) which resulted in the code being executed on every component render.
  • Exposes convenient references to the context instance and the contextSafe() function as method parameters as well as object properties that get returned by the useGSAP() hook.
  • Like 1
Link to comment
Share on other sites

Hi,

 

Just a simple note regarding @newguy123's demo. There is no need to declare the helper function inside the component, since any re-render will read and declare the method again and again. For this type of scenarios is better to just create a helpers folder and export the method from a specific file, like that not only you're not declaring the method again but your component looks far cleaner as well:

https://stackblitz.com/edit/react-wqhfm6?file=src%2Fhelpers%2FimageSequence.js,src%2FApp.js

 

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...