Jump to content
Search Community

Gsap just works correctly when I resize window explorer

MikeG95 test
Moderator Tag

Recommended Posts

Hey guys Im getting crazy with using Angular and Gsap.

 

I recorded a video.

 

Look at the markers.

 

First-load without resize:

https://gyazo.com/bc0061365a7614646806450e17f3c1f5

 

 

Resizing window

https://gyazo.com/f259d4f0aebecd5acdd5152aa2dad6d2

 

 

 

I have multiples components and I want to use gsap on footer. The markers are wrong when i load my page but If i resize the window there are in the correct place and the animations works

 correctly.

 

Im Using: Angular, Bootstrap and Gsap

<div class=" container-fluid pb-0 mb-0 justify-content-center text-light " #footer>
  <footer #Infooter>
      <div class="row my-5 justify-content-center py-5">
          <div class="col-11">
              <div class="row ">
                  <div class="col-xl-8 col-md-4 col-sm-4 col-12 my-auto mx-auto a">
                      <h3 class="text-muted mb-md-0 mb-5 bold-text">Pepper.</h3>
                  </div>
                  <div class="col-xl-2 col-md-4 col-sm-4 col-12">
                      <h6 class="mb-3 mb-lg-4 bold-text "><b>MENU</b></h6>
                      <ul class="list-unstyled">
                          <li>Home</li>
                          <li>About</li>
                          <li>Blog</li>
                          <li>Portfolio</li>
                      </ul>
                  </div>
                  <div class="col-xl-2 col-md-4 col-sm-4 col-12">
                      <h6 class="mb-3 mb-lg-4 text-muted bold-text mt-sm-0 mt-5"><b>ADDRESS</b></h6>
                      <p class="mb-1">605, RATAN ICON BUILDING</p>
                      <p>SEAWOODS SECTOR</p>
                  </div>
              </div>
              <div class="row ">
                  <div class="col-xl-8 col-md-4 col-sm-4 col-auto my-md-0 mt-5 order-sm-1 order-3 align-self-end">
                      <p class="social text-muted mb-0 pb-0 bold-text"> <span class="mx-2"><i class="fa fa-facebook" aria-hidden="true"></i></span> <span class="mx-2"><i class="fa fa-linkedin-square" aria-hidden="true"></i></span> <span class="mx-2"><i class="fa fa-twitter" aria-hidden="true"></i></span> <span class="mx-2"><i class="fa fa-instagram" aria-hidden="true"></i></span> </p><small class="rights"><span>&#174;</span> Pepper All Rights Reserved.</small>
                  </div>
                  <div class="col-xl-2 col-md-4 col-sm-4 col-auto order-1 align-self-end ">
                      <h6 class="mt-55 mt-2 text-muted bold-text"><b>ANIRUDH SINGLA</b></h6><small> <span><i class="fa fa-envelope" aria-hidden="true"></i></span> anirudh@gmail.com</small>
                  </div>
                  <div class="col-xl-2 col-md-4 col-sm-4 col-auto order-2 align-self-end mt-3 ">
                      <h6 class="text-muted bold-text"><b>RISHABH SHEKHAR</b></h6><small><span><i class="fa fa-envelope" aria-hidden="true"></i></span> rishab@gmail.com</small>
                  </div>
              </div>
          </div>
      </div>
  </footer>
</div>
body {
  background: linear-gradient(0deg, #fff, 50%, #DEEEFE);
  background: #455A64;
  height: 100 !important
}

.container-fluid {
  background: #262626;
  color: #627482 !important;
  margin-bottom: 0;
  padding-bottom: 0
}

small {
  font-size: calc(12px + (15 - 12) * ((100vw - 360px) / (1600 - 360))) !important
}

.bold-text {
  color: #989c9e !important
}

.mt-55 {
  margin-top: calc(50px + (60 - 50) * ((100vw - 360px) / (1600 - 360))) !important
}

h3 {
  font-size: calc(34px + (40 - 34) * ((100vw - 360px) / (1600 - 360))) !important
}

.social {
  font-size: 21px !important
}

.rights {
  font-size: calc(10px + (12 - 10) * ((100vw - 360px) / (1600 - 360))) !important
}
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';

gsap.registerPlugin(ScrollTrigger);

@Component({
  selector: 'app-footer',
  templateUrl: './footer.component.html',
  styleUrls: ['./footer.component.scss']
})
export class FooterComponent implements OnInit {

  @ViewChild ('footer', { static: true }) public footer: ElementRef<HTMLDivElement>;
  @ViewChild ('Infooter', { static: true }) public Infooter: ElementRef<HTMLDivElement>;

  constructor() {}

  ngOnInit(): void {
    this.initFooterAnimations();

  }


  initFooterAnimations(): void {
  gsap.to(this.footer.nativeElement, {
    scrollTrigger: {
      trigger: this.footer.nativeElement,
      scrub: true,
      start: '40% bottom',
    },
    duration: 0.6,
    y: -90,
  });
  gsap.to(this.Infooter.nativeElement, {
    scrollTrigger: {
      trigger: this.Infooter.nativeElement,
      scrub: true,
      start: '-200px bottom',
      markers: true
    },
    duration: 1,
    y: -190,
  });
  }
}

There is my app.component angular html:

<app-header></app-header>
<app-body></app-body>
<app-footer></app-footer>
<router-outlet></router-outlet>

 

Link to comment
Share on other sites

41 minutes ago, Cassie said:

I'm not an angular person but is there a way to check if the DOM content is loaded first before running the animtion code?

Im not an angular person too :( there is some info about angular lifecycle events. https://angular.io/guide/lifecycle-hooks

 

I tried it with ngAfterview but not changes.

 

Maybe im not writing it correctly.

 

Link to comment
Share on other sites

You're also animating the y position of the elements that you're using as triggers. Is that intentional?

Maybe pop together a minimal demo and we'll see if we can help.

Otherwise maybe one of these angular forums might be able to give you some pointers?
 

gsap.to(this.footer.nativeElement, {
    scrollTrigger: {
      trigger: this.footer.nativeElement,
      scrub: true,
      start: '40% bottom',
    },
    duration: 0.6,
    y: -90,
  });
  gsap.to(this.Infooter.nativeElement, {
    scrollTrigger: {
      trigger: this.Infooter.nativeElement,
      scrub: true,
      start: '-200px bottom',
      markers: true
    },
    duration: 1,
    y: -190,
  });
  }

 

Link to comment
Share on other sites

17 hours ago, Cassie said:

You're also animating the y position of the elements that you're using as triggers. Is that intentional?

Maybe pop together a minimal demo and we'll see if we can help.

Otherwise maybe one of these angular forums might be able to give you some pointers?
 



gsap.to(this.footer.nativeElement, {
    scrollTrigger: {
      trigger: this.footer.nativeElement,
      scrub: true,
      start: '40% bottom',
    },
    duration: 0.6,
    y: -90,
  });
  gsap.to(this.Infooter.nativeElement, {
    scrollTrigger: {
      trigger: this.Infooter.nativeElement,
      scrub: true,
      start: '-200px bottom',
      markers: true
    },
    duration: 1,
    y: -190,
  });
  }

 

Yes it is intentional, yep maybe asking on angular forums could help me, this is what I did to investigate when Gsap is loaded:

 

 

I writed it to show in console

import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';


@Component({
  selector: 'app-footer',
  templateUrl: './footer.component.html',
  styleUrls: ['./footer.component.scss']
})
export class FooterComponent implements AfterViewInit  {

  @ViewChild ('footer', { static: true }) public footer: ElementRef<HTMLDivElement>;
  @ViewChild ('Infooter', { static: true }) public Infooter: ElementRef<HTMLDivElement>;

  constructor() {}
  ngOnInit(): void {
    gsap.registerPlugin(ScrollTrigger);
    console.log("onInit called")
  }
  ngDoCheck(){
    console.log("do check")
  }

ngAfterViewInit() {
  this.initFooterAnimations();
  
    console.log("after view init")
}
  initFooterAnimations(): void {
  gsap.to(this.Infooter.nativeElement, {
    scrollTrigger: {
      trigger: this.Infooter.nativeElement,
      scrub: true,
      start: '-200px bottom',
      markers: true
    },
    duration: 1,
    y: -190,
  });
  }
}

And there is the result:

 

ddf0bec32f4862e2191406aa36e7123a.png

 

 

 

Link to comment
Share on other sites

2 minutes ago, MikeG95 said:

Yes it is intentional, yep maybe asking on angular forums could help me, this is what I did to investigate when Gsap is loaded:

 

 

I writed it to show in console


import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';


@Component({
  selector: 'app-footer',
  templateUrl: './footer.component.html',
  styleUrls: ['./footer.component.scss']
})
export class FooterComponent implements AfterViewInit  {

  @ViewChild ('footer', { static: true }) public footer: ElementRef<HTMLDivElement>;
  @ViewChild ('Infooter', { static: true }) public Infooter: ElementRef<HTMLDivElement>;

  constructor() {}
  ngOnInit(): void {
    gsap.registerPlugin(ScrollTrigger);
    console.log("onInit called")
  }
  ngDoCheck(){
    console.log("do check")
  }

ngAfterViewInit() {
  this.initFooterAnimations();
  
    console.log("after view init")
}
  initFooterAnimations(): void {
  gsap.to(this.Infooter.nativeElement, {
    scrollTrigger: {
      trigger: this.Infooter.nativeElement,
      scrub: true,
      start: '-200px bottom',
      markers: true
    },
    duration: 1,
    y: -190,
  });
  }
}

And there is the result:

 

ddf0bec32f4862e2191406aa36e7123a.png

 

 

 

In this proyect I m  bringing any img(logos,background...) and Text(<p>) from my own api to <header> and <body>, maybe gsap is loading before than this api?

Link to comment
Share on other sites

I'm not an Angular guy either, but it sure sounds like you must be loading things that affect layout AFTER the page's "load" event fires. So just make sure you call ScrollTrigger.refresh() after you're done adding/loading anything to the page that affects layout. 

  • Like 1
Link to comment
Share on other sites

5 hours ago, GreenSock said:

I'm not an Angular guy either, but it sure sounds like you must be loading things that affect layout AFTER the page's "load" event fires. So just make sure you call ScrollTrigger.refresh() after you're done adding/loading anything to the page that affects layout. 

It works but only if use ngAfterVIewChecked that is called every time Angular has finished running change detection on a component , now im sure that is a problem with angular but with this kind of call funcition is doing scrollrefresh in every component in the same load, its not a solution, it would works with ngAfterView but it desnt. I gonna post on Angular Forums and maybe i will come back with a solution.

 

Thanks guys

  • Like 2
Link to comment
Share on other sites

On 5/25/2021 at 12:44 PM, MikeG95 said:

It works but only if use ngAfterVIewChecked that is called every time Angular has finished running change detection on a component , now im sure that is a problem with angular but with this kind of call funcition is doing scrollrefresh in every component in the same load, its not a solution, it would works with ngAfterView but it desnt. I gonna post on Angular Forums and maybe i will come back with a solution.

 

Thanks guys

Would be great if you share your solution.. Same problem. With ngAfterViewChecked it will work but the function triggers every ms on the site. I dont really know if its good for the performance on huge sites.  Soft Reloads (only f5)/Routing changes will break the markers.

 

I asked all my colleauges at work for a solution but no one got any solutions for this problem. 

Link to comment
Share on other sites

  checked: boolean = false;

  ngAfterContentChecked(): void {
    if (!this.checked) {
      this.checked = true;
      setTimeout(() => {
        ScrollTrigger.refresh();
        this.initScrollAnimation();
      }, 1);
    }
  }
  ngOnInit(): void {
      this.initialAnimations(); 
  }

@MikeG95

If you use this code it will work but the solution is not that great... You will not notice the 1ms timeout on reloads/routing. You can change it to .1 or  .0001 and it will work too. Dont forget to kill the triggers on each component when you got multiple components with animations.

 

 

  ngOnDestroy(): void {
    let triggers = ScrollTrigger.getAll();
    triggers.forEach((trigger) => {
      trigger.kill(true);
    });
  }

 

Edited by NiceBone
  • Like 1
Link to comment
Share on other sites

On 5/26/2021 at 6:00 PM, NiceBone said:

  checked: boolean = false;

  ngAfterContentChecked(): void {
    if (!this.checked) {
      this.checked = true;
      setTimeout(() => {
        ScrollTrigger.refresh();
        this.initScrollAnimation();
      }, 1);
    }
  }
  ngOnInit(): void {
      this.initialAnimations(); 
  }

@MikeG95

If you use this code it will work but the solution is not that great... You will not notice the 1ms timeout on reloads/routing. You can change it to .1 or  .0001 and it will work too. Dont forget to kill the triggers on each component when you got multiple components with animations.

 

 


  ngOnDestroy(): void {
    let triggers = ScrollTrigger.getAll();
    triggers.forEach((trigger) => {
      trigger.kill(true);
    });
  }

 

 

 

I found the problem, but I coundt get the solution, the problem is that we are using an api and its loads after than ngAfterView I was consulting this problem on Angular Forums and they told my that I have to use rxjs with SwitchMap Tool to get our api petition before than ScrollRefresher, but Im noob on Angular, I being 4 days trying to do it work but imopssible for me maybe in the future I will undertand it

 

https://i.gyazo.com/80761cf8cd9aa673e1ece1ba8ee6a36f.png

 

 

 

Here is my post on Angular forums

https://www.reddit.com/r/Angular2/comments/nlfkuw/i_need_to_execute_a_function_after_my_api/

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