Jump to content
Search Community

Background images increasing, rising and locking until the last one.

Alexandre Araujo test
Moderator Tag

Go to solution Solved by mvaneijgen,

Recommended Posts

Hello everybody.
My first participation in the support forum, congratulations to the developers involved in this work.
I'm using Google translate to help with communication.

I'm trying unsuccessfully to make a specific animation.

When the page loads, part of the first image from the "images-cases" section appears, with scale: 0.91.
When you start scrolling, the "banner-header" section rises normally and the idea is that the first image in the "images-cases" section starts to rise, increasing the scale so that, when it reaches the top of the bowser window, it stay locked (pin) and reach scale: 1.

At this moment, the second image will be partially appearing at the bottom of the window with scale: 0.91 and the first image, which will be occupying 100% of the browser window, must remain still (pin). Either it, or the "images-cases" section. I tried coding both cases but I didn't get the expected result.

When continuing to scroll, the second image follows the same behavior as the first (rises and increases to scale: 1), stopping at the top and the third appears partially at the bottom of the window.
This will happen with all images selected for this animation, without limits.

After the last image rises, enlarges and stops, continuing to scroll brings the last "epilogue" section rising normally.
I appreciate any help.

 

See the Pen jOXYbew by xando_arau (@xando_arau) on CodePen

Link to comment
Share on other sites

Hi @Alexandre Araujo welcome to the forum!

 

I would suggest going a different route. Instead of multiple ScrollTriggers with multiple tweens, why not use a timeline with just one ScrollTrigger, this will make things much more easy to debug and manage. 

 

I've tweaked your pen a bit and have move things around so that they all stack right on top of each other, see here. 

 

See the Pen eYbyzYv?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen

 

Then, the best thing to do when working with ScrollTrigger is to remove it! This seems counter intuitive, but ScrollTrigger is just animating something on scroll, so just focus on the animation at first and only when you're happy with the animation add ScrollTrigger back in. This way you can focus on one part at a time and it will save a lot of headache when debugging. 

 

See the Pen bGOaegV?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen

 

If that is looking like you want, you can enable ScrollTrigger and see how that works 

 

See the Pen yLGpJgM?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen

 

Hope it helps and happy tweening! 

  • Like 1
Link to comment
Share on other sites

Hi mvaneijgen, thanks for the quick response.
The visual result is basically what I imagined, I could use it to make the fine adjustments I need, but the change that was made to the HTML structure (including a <div> encompassing the top two sections) and the use of css grid, maybe not are compatible with everything that has already been developed in the project where I intend to include this animation.
The number of images is also not fixed and does not allow me to use fixed yPercent settings for each child, I will need to think about how to do this dynamically.
But the idea in general of removing the ScrollTrigger animation and then including it was super valid, I will proceed with the necessary changes in my project.
If it is possible to leave this topic open for now, I will return another day with a new result and considerations.
Thank you very much again for this help 😃

  • Like 1
Link to comment
Share on other sites

That is all fine, CSS Grid is just something that is a quick route to centering things right on top of each other, feel free to do the same with the 100 other ways to center things in CSS and choose the one that best suits your project. 

 

Personally I like to build it not dynamic at first, because then you can see patterns emerge and thus it will be easier to optimise. As you can see in the above example, only the first one is different, so one tween for the first element and then a stagger for each following image is all you're going to need I think. 

 

Good luck with the project!

  • Like 1
Link to comment
Share on other sites

Hi mvaneijgen.


I made adaptations to the code you sent, so that the animation was exactly as I need it, but I still have problems resolving it, follow the updated link below.
Before posting on the forum I had been trying to solve it for days, I have 8 different codes commented here, all failed attempts.
With your code I tried a few more variations without success and if it is possible, I would need more help.
The animation sequence is as follows:
When you start scrolling, the first image (which is already partially appearing at the bottom of the screen) starts to rise and enlarge.
Soon after it begins its movement, the second image has to rise and remain still at the same scale and position as the first one, before moving.
At the end of the movement of the first, the second moves again, rising and increasing.
In your code, the next image only appears after the first one has already occupied the entire screen, that is, the movement of the next image to partially rise waits for the previous one to finish.
I need the animations to happen together at the beginning, the first one starts to rise and the second one already stops where the first one was before.
It may seem like a detail, but the project requires it, I've been trying for days to create this behavior, and I can't.
Could you once again help me in this regard?

 

I would also like to take this opportunity to ask about another issue that needs to happen in this animation.
I tried to use a code model to trigger the rise and increase movement, when the user clicks on the part of the image that appears at the bottom of the screen, the demo below has this functionality.
When clicking, the image executes its animation and stops with the next image appearing at the bottom of the screen.
But from what I can see, the movement of the images can be considered as a "single" animation and therefore, I am having problems applying the movement to one image at a time (detect the start and end position of each image).
I tried to use a dynamic start positioning, but it's not working properly.
Thank you once again.

 

See the Pen bGOvopY?editors=1010 by xando_arau (@xando_arau) on CodePen

Link to comment
Share on other sites

  • Solution
Quote

 

Then, the best thing to do when working with ScrollTrigger is to remove it! This seems counter intuitive, but ScrollTrigger is just animating something on scroll, so just focus on the animation at first and only when you're happy with the animation add ScrollTrigger back in. This way you can focus on one part at a time and it will save a lot of headache when debugging. 

 

I can't say it enough, this is so important, you're making an animation, so to fix the animation you have to focus on the animation!

 

What I've done is enable GSDevTools, to get a progress bar that lets me manipulate the timeline. You say you want the second case to pop up when the other still is playing? That sounds like a job for the position parameter to me, with it we can tell a tween to start at a certain point of the previous tween (or next tween). I've now set it to start -=50% of the previous tween and then it animaties to full and the following case does the same. You can of course tweak the timing, but this is a good starting point 

 

See the Pen dywmZYV?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen

 

Next up, your scrollTo code seems solid! I only would go a more simple route. You can add labels to your timeline and with GSDevTools it's easy to check where you want these labels to be! And then instead of creating new ScrollTriggers, we tell the scrollTo plugin to tween to the labels we have defined in the timeline. Hope it helps and happy tweening! 

 

See the Pen xxmWPRq?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen

  • Like 2
Link to comment
Share on other sites

Wonderful! I didn't know Position Parameteres, extremely powerful.
For now I'm not a member of the Club, so I can't use GSDevTools, but I found this tool very interesting too. I'm considering joining, we'll see soon.
Now everything is working as expected, I'll just need to think about the dynamism of this code for indefinite amounts of images.
Thank you very much for these precious tips, it took me days of work without being able to achieve what you accomplished in 2 shots 😃
Strong hug!

  • Like 2
Link to comment
Share on other sites

Hi everyone.

 

I've been updating my project, inserted a filter reducing the brightness in the image that is in evidence, included a call to action and I thought it would be interesting to insert a snap in the movement of the images.
After researching options and making some attempts, always thinking about scrolling with the scroll bar and scrolling when clicking on the image, the one that worked best, stopping at the exact point of each image, was using snapTo: "labelsDirectional", or just snapTo : "labels", but even placing it inside the ScrollTrigger, the action happens alone as soon as the page loads.
Interestingly, this behavior does not happen in Codepen, only when I access my project in the browser. I tested on Chrome, Edge and Firefox, Windows and Mac, local environment and on an AWS server.
As you won't see the problem on Codepen, I don't know if you'll be able to help me, but is there a property that keeps the snap disabled until the user uses one of the two scroll options?
Another detail is that when scrolling back up, the first image (last in this sequence) has the snap active across the entire height of the screen, only when the image reaches the bottom does it remain in position.
Thank you for this additional help.

 

See the Pen ExGLVLW by xando_arau (@xando_arau) on CodePen

Link to comment
Share on other sites

Hi,

 

The reason the issue doesn't happen on your codepen is because the body has is natural margin of 8px, so the markers are not at the top of the viewport:

BTqhy3v.png

If you add margin: 0 to the body tag those markers are at the top of the viewport and the issue happens.

 

Now what strikes me as odd is that you have this section with home-banner class that is supposed to have a height of 50vw but the image-cases section is on top of that element. You can see it if you remove all the JS from your codepen demo:

JomdK3D.png

The red line there is a border-top property I added to the image-cases section, so as you can see this is a CSS issue and not a GSAP related one.

 

You should review the grid display you have in your setup in order to make it work.

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

Hi Rodrigo, thanks for the answer.

 

In fact, this HTML/CSS grid solution, placing ".imagem-cases" over the ".home-banner" section and wrapping both with a "#wrapp-cases" div, was suggested by colleague mvaneijgen, to solve the animation I needed to be executed. I was really lost on how to make everything work the way it is now, the first image rising, enlarging and locking, so that the next ones rise, enlarge and hover over it (briefly).
I understand the problem, it's precisely the snap being activated, because the element is already in a start position, but with this suggested solution I don't know how to resolve this snap detail.
If I have to redo the HTML structure and the CSS, it will be necessary to reprogram the GSAP animation and then I'll go back to the situation I was in when I created this topic 😕
Any suggestion?

 

Thank you once again.

 

With body margin 0 to reproduce de problem: 

See the Pen BavxpPb by xando_arau (@xando_arau) on CodePen

Link to comment
Share on other sites

If the HTML/CSS can't be touched to achieve the result you're looking for, the simplest approach I can think is to give he start point of the ScrollTrigger instance a value bigger than the top of the viewport, perhaps 10 in order to emulate to some degree the result you're getting in the codepen due to the natural margin of the body tag:

scrollTrigger: {
  start: "top 10", // when the top of the trigger gets to 10 px from the top of the viewport
  ...
}

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

Hi Rodrigo.


I followed your idea, changing the start of the ScrollTrigger, to place it slightly lower than the top. Resolved the unwanted snap activation, but like a domino effect, the images were stopping further up, leaving a 10px space between them and the bottom of the screen. I would have to compensate somehow in the timeline and in addition, when scrolling up, two images were going up at once, with minimal movement of the scroll bar. I think it caused a mess that would need to be studied to fix everything.
So instead of changing the JS, I changed the CSS by putting margin-top: 10px in ".images-cases". Everything is apparently working fine, the only thing that remains bad is the snap of the first image when we scroll up. It continues to be drawn back up until the upward scroll is completed.
If there is a way to disable the snap to the first image (only when scrolling up), it would be satisfactory. I don't know if you know the term "Gambiarra" hahaha, but now I think I'm falling into that category :P
By the way, when I said that it wouldn't be interesting to change the HTML/CSS, it was only because everything was ready, using mvaneijgen's solution, where he changed some things in the HTML/CSS structure that I had created.
If with my initial structure (where the ".images-cases" was not positioned above the ".home-banner" and there was not even a div involving both), this exact behavior could be reproduced, it would be super valid too, the problem is that I still haven't acquired enough knowledge of GSAP to undo what has been done and apply it in another way 😕


Below everything works, except the snap of the last image scrolling up:

See the Pen qBLYMyJ by xando_arau (@xando_arau) on CodePen

Link to comment
Share on other sites

Hi,

 

The simplest way is to add a label at the start of the timeline, before every other instance:

const tl = gsap.timeline({
  defaults: {
    paused: false,
    ease: "none",
    duration: 2
  },
  scrollTrigger: {...}
});
tl.add("start");

That adds an extra stop at the start of the timeline and probably would make all the margins and other stuff to offset everything 10 pixels down not needed, but you'd have to test and see. Here is a fork of your codepen:

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

 

Other than that it would require to write all the logic for the snapTo on a function in order to check the direction of the ScrollTrigger instance, current progress and check where the ScrollTrigger instance should land.

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

Hi Rodrigo, it's working perfectly.


But I confess that it took me a while to understand how an extra label with any string solved the problem.
To be clear for other people who may need similar behavior, if you were to render this, it would look like a stack of labels (of snap targets).

<label="start">
<label=case1>
<label=case2>
<label=case3>

And then with the image of case1 being displayed, when scrolling up the snap points to "start" which is a "fake label" above case1.
It didn't work before, because without this fake label, when you reached the first case, the snap no longer had superior labels to point to.
Simple but ingenious.

Thank you very much for this help.

  • Like 1
Link to comment
Share on other sites

Hey guys.

 

I need a little more help on this same project, please.
I changed the animation code so that it was more dynamic, regardless of the number of cases.
I also made an animation on the CTA button and everything is working fine, except the snap for the last case.
I explain the problem in comments in the js code of this Codepen below.
If anyone can explain to me what I'm doing wrong, I'd appreciate it.

 

The error happens when you click on the last case to go up.


Yours sincerely,
Alexander.

 

image.png.2a588191c151c958170820b9bca9c339.png

 

See the Pen jOXvwWY by xando_arau (@xando_arau) on CodePen

Link to comment
Share on other sites

Hi,

 

This is mostly a faulty logic issue that clearly stems from here:

  if ( index < arrCases.length - 1 ) {
    tl.to(`#case${index + 1}`, {
      yPercent: 75
    }, `case${index}` + "-=2");
  }

For loops is always better to use an array of DOM elements created with GSAP's toArray() utility method:

https://greensock.com/docs/v3/GSAP/UtilityMethods/toArray()

 

And run a conditional check if an element with that index value exists.

 

Another option is to check this has well:

  if ( index < arrCases.length - 1 && arrCases[index + 1] ) {
    tl.to(`#case${index + 1}`, {
      yPercent: 75
    }, `case${index}` + "-=2");
  }

Finally your buttons are not working since you are using <a> tags, is better (for codepens at least) to just use buttons.

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

Hello Rodrigo.

Once again, thanks for your attention and I'm sorry for the delay, I was working on another project these days.


The "arrCase" array is assembled in the initial forEach where I use the "links" array, which was generated by the method you mentioned, toArray.
I took advantage of this initial loop to create an extra array that could be used later in the loop to make the animation dynamic.
I don't understand why this might be a problem, it's just a new forEach being executed on a new array.

The option you suggested below to check if everything is ok, including the

 

&& arrCases[index + 1]

condition in the IF, had no effect 😕

 

Regarding the buttons, (I imagine you are referring to the buttons written "conheça o projeto"), they are working without errors. In my demo they are useless, but in the project they open the case page.

 

What I can't understand is the simple and direct command to create a label tl.addLabel(`#case${index}`, '>'), not being executed after the IF.
Then it doesn't create the last label and when you click on the image, the scroll goes up instead of going down 😕


I will continue testing options.
Thanks!

Link to comment
Share on other sites

Hi,

 

Honestly I can't tell you what's the issue. I added a couple of console calls and I'm getting the right calls:

arrCases.forEach((a, index) => {
  console.log(`#case${index}`); // #case0 - #case1 - #case2
  
  tl.addLabel(`#case${index}`, '>')

});

console.log(tl.labels)
/*
#case0: 2.5
#case1: 5
#case2: 7.5
case0: 2.5
case1: 5
start: 0
*/

As you can see the label is actually being added to the timeline.

 

Sometimes loops can be tricky and deceitful. When I struggle to get a loop working I write everything manually in order to get the pattern and create the loop correctly. Also if you have two sets of DOM nodes that have the same amount of elements, is better to create an array for each one, run a loop for one set and get the corresponding element using the index value of the loop:

const arrOne = gsap.utils.toArray(".class-one");
const arrTwo = gsap.utils.toArray(".class-two");

arrOne.forEach((el, i) => {
  // grab the element of the other array
  const elTwo = arrTwo[i];
});

Hopefully this helps.

Happy Tweening!

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