banner



How To Use Angular 4 Animations To Scrolltop 0

Source: Twitter logo

I'm creating a webpage having full page width/height div's. While scrolling down I've two types of methods.

Scroll on Click

                          //HTML              <a (click)="goToDiv('about')"></a>              //JS              goToDiv(id) {              let              element =              certificate.querySelector("#"+id);         element.scrollIntoView(element);       }                      

Roll on HostListener

                          @HostListener("window:curlicue", ['$event'])              onWindowScroll($event: any):              void              {              this.topOffSet              =              window.pageYOffset;              //window.scrollTo(0, this.topOffSet+662);              }                      

1. How to add together a scrolling animation furnishings?

Only like :

            $('.scroll').on('click',              function(e) {     $('html, torso').animate({              scrollTop: $(window).height()     },              1200); });                      

2. And how to use HostListener to scroll to next div?

This one is fun. The solution, equally with near things angular 2, is observables.

                              getTargetElementRef(currentYPos: int):                ElementRef                {                // you need to figure out how this works                // I can't annotate much on it without knowing more than nearly the page                // but you lot inject the host ElementRef in the component / directive constructor and apply normal vanillaJS functions to find other elements                }                //capture the scroll event and pass to a part that triggers your own event for clarity and and then y'all tin manually trigger                scrollToSource:                Field of study<int> =                new                Subject<int>();   @HostListener("window:scroll", ['$outcome'])                onWindowScroll($issue: any):                void                {                var                target =                getTargetElementRef(window.pageYOffset);                this.scrollTo(target);   }                scrollTo(target:                ElementRef):                void                {                // this assumes you lot're passing in an ElementRef, it may or may not be advisable, you can pass them to functions in templates with template variable syntax such as: <div #targetDiv>Scroll Target</div> <button (click)="scrollTo(targetDiv)">Click To Scroll</button>                this.scrollToSource.next(target.nativeElement.offsetTop);   }                //switch map takes the concluding value emitted past an observable sequence, in this case, the user'southward latest scroll position, and transforms it into a new appreciable stream                this.scrollToSource.switchMap(                  targetYPos                  =>                {                return                Observable.interval(100)                //interval just creates an observable stream corresponding to time, this emits every ane/10th of a second. This tin be fixed or brand it dynamic depending on the distance to scroll                .scan((acc, curr) =>                acc +                5,                window.pageYOffset)                // scan takes all values from an emitted observable stream and accumulates them, here you're taking the current position, adding a scroll step (fixed at 5, though this could also be dynamic), and then so on, its like a for loop with +=, just you emit every value to the side by side operator which scrolls, the second argument is the kickoff position                .exercise(                  position                  =>                window.scrollTo(0, position))                /// here is where you curlicue with the results from scan                .takeWhile(                  val                  =>                val < targetYPos);                // terminate when yous get to the target                }).subscribe();                //don't forget!                          

With a click this is easy to use. You simply bind scrollTo to a click

This only works for scrolling in 1 management, Nevertheless this should get yous started. You can make browse smarter so it subtracts if you need to become upwards, and instead use a function inside takeWhile that figures out the correct termination condition based on if going up or down.

edit: rxjs five+ compatible version

                              this.scrollToSource.piping(switchMap(                  targetYPos                  =>                interval(100).pipage(                //interval just creates an observable stream respective to time, this emits every ane/10th of a second. This can be fixed or make it dynamic depending on the distance to ringlet                scan((acc, curr) =>                acc +                v,                window.pageYOffset),                // scan takes all values from an emitted observable stream and accumulates them, hither you're taking the electric current position, adding a coil stride (fixed at 5, though this could too be dynamic), and then so on, its like a for loop with +=, but y'all emit every value to the next operator which scrolls, the 2nd statement is the start position                takeWhile(                  val                  =>                val < targetYPos))                // stop when you lot get to the target                )).subscribe(                  position                  =>                window.scrollTo(0, position));                // hither is where y'all scroll with the results from browse                          

I spent days trying to effigy this out. Beingness a newbie I tried many things and none of them piece of work. Finally, I have a solution so I will post it here.

There are two steps:

  1. Animate when things announced.
  2. Make things appear when scrolling.

Part i: I found out these two keen tutorials for newbies:

  1. The almost basic one
  2. The ane that actually animates when stuff appears

Part 2: I simply discover the solution in this answer


Role 1 Stride by Footstep:

  1. Add together the line import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; to /src/app/app.module.ts and then also:
              @NgModule({                // Other arrays removed                imports: [                // Other imports                BrowserAnimationsModule                ], })                          
  1. In the component.ts you want to animate, add together: import { trigger,state,manner,transition,breathing } from '@angular/animations'; And and so:
              @Component({                // Here goes the selector and templates and etc.                animations: [                trigger('fadeInOut', [                country('void',                style({                opacity:                0                })),                transition('void <=> *',                breathing(1000)),     ]),   ] })                          
  1. Finally, in the HTML item you desire to breathing, add together [@fadeInOut].

If everything was done correctly, yous should at present have an animation (simply it happens as soon as the webpage loads and not when you scroll.

Part 2 Step by Step:

  1. Create a file .ts like for example appear.ts and copy-paste this code:
                              import                {                ElementRef,                Output,                Directive,                AfterViewInit,                OnDestroy,                EventEmitter                }                from                '@angular/core';                import                {                Observable,                Subscription, fromEvent }                from                'rxjs';                import                { startWith }                from                'rxjs/operators';                //import 'rxjs/add/observable/fromEvent';                //import 'rxjs/add together/operator/startWith';                @Directive({                selector:                '[appear]'                })                export                class                AppearDirective                implements                AfterViewInit,                OnDestroy                {     @Output()                appear:                EventEmitter<void>;                elementPos: number;                elementHeight: number;                scrollPos: number;                windowHeight: number;                subscriptionScroll:                Subscription;                subscriptionResize:                Subscription;                constructor(private element: ElementRef){                this.appear                =                new                EventEmitter<void>();     }                saveDimensions() {                this.elementPos                =                this.getOffsetTop(this.element.nativeElement);                this.elementHeight                =                this.chemical element.nativeElement.offsetHeight;                this.windowHeight                =                window.innerHeight;     }                saveScrollPos() {                this.scrollPos                =                window.scrollY;     }                getOffsetTop(chemical element: whatever){                let                offsetTop = element.offsetTop                ||                0;                if(chemical element.offsetParent){         offsetTop +=                this.getOffsetTop(chemical element.offsetParent);       }                return                offsetTop;     }                checkVisibility(){                if(this.isVisible()){                // double check dimensions (due to async loaded contents, due east.g. images)                this.saveDimensions();                if(this.isVisible()){                this.unsubscribe();                this.announced.emit();         }       }     }                isVisible(){                return                this.scrollPos                >=                this.elementPos                || (this.scrollPos                +                this.windowHeight) >= (this.elementPos                +                this.elementHeight);     }                subscribe(){                this.subscriptionScroll                =                fromEvent(window,                'whorl').pipage(startWith(null))         .subscribe(() =>                {                this.saveScrollPos();                this.checkVisibility();         });                this.subscriptionResize                =                fromEvent(window,                'resize').pipe(startWith(nix))         .subscribe(() =>                {                this.saveDimensions();                this.checkVisibility();         });     }                unsubscribe(){                if(this.subscriptionScroll){                this.subscriptionScroll.unsubscribe();       }                if(this.subscriptionResize){                this.subscriptionResize.unsubscribe();       }     }                ngAfterViewInit(){                this.subscribe();     }                ngOnDestroy(){                this.unsubscribe();     }   }                          
  1. Import it using import {AppearDirective} from './timeline/announced';and add it to the imports every bit:
              @NgModule({                declarations: [                // Other declarations                AppearDirective                ],                // Imports and stuff                          
  1. Somewhere in the form do:
              hasAppeared : boolean =                fake;                onAppear(){                this.hasAppeared                =                truthful;                console.log("I have appeared!");                // This is a good idea for debugging                }                          
  1. Finally, in the HTML add the ii post-obit:
              (appear)="onAppear()"                *ngIf="hasAppeared"                          

Y'all can bank check this is working by checking the console for the bulletin "I accept appeared!".

The @bryan60 answer works, only I was not comfortable with information technology, and I preferred to use TimerObservable which seems less disruptive for other teammates and likewise easier to customize for time to come uses.

I suggest you lot have a shared service for times you're touching DOM, or working with scroll and other HTML element related issues; And then you can have this method on that service (otherwise having it on a component does not brand any problem)

                              // Cull the target element (see the HTML lawmaking bellow):                @ViewChild('myElement')                myElement:                ElementRef;                this.scrollAnimateAvailable:boolean;                animateScrollTo(target: ElementRef) {                if                (this.helperService.isBrowser()) {                this.scrollAnimateAvailable                =                true;                TimerObservable                .create(0,                20).pipe(                takeWhile(() =>                this.scrollAnimateAvailable)).subscribe((e) =>                {                if                (window.pageYOffset                >= target.nativeElement.offsetTop) {                window.scrollTo(0,                window.pageYOffset                - due east);         }                else                if                (window.pageYOffset                <= target.nativeElement.offsetTop) {                window.scrollTo(0,                window.pageYOffset                + due east);         }                if                (window.pageYOffset                +                30                > target.nativeElement.offsetTop                &&                window.pageYOffset                -                xxx                < target.nativeElement.offsetTop) {                this.scrollAnimateAvailable                =                faux;         }        });     }    }                scrollToMyElement(){                this.animateScrollTo(this.myElement)   }                          

You need to pass the element to this method, here is how you tin practise it:

              <a (click)="scrollToMyElement()"></a> <!--                Lots                of                things here... -->                                  <div                    #myElement>                  </div>                                          

Copyright © 2022 QueryThreads

All content on Query Threads is licensed under the Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA 3.0).

Source: https://www.querythreads.com/angular-4-scroll-animation/

Posted by: thomasexprooking.blogspot.com

0 Response to "How To Use Angular 4 Animations To Scrolltop 0"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel