Friday, February 17, 2017

Recipe for creating parallax effect of background image in Angular 2.0 Typescript

import { HostListener, Component, OnChanges, Directive, Input, Output, EventEmitter, SimpleChange, ElementRef} from '@angular/core';

Here is the directive:

@Directive({
    selector: '[track-scroll]',
    //host: {'(window:scroll)': 'track($event)'},
 
})

export class TrackScrollComponent {

  @Output() notify: EventEmitter = new EventEmitter();
  @HostListener('scroll', [''])
    track() {
        console.debug("Scroll Event");
        //console.debug(this._elementRef.nativeElement.scrollTop);
        this.notify.emit(this._elementRef.nativeElement.scrollTop);
    }
   constructor(private _elementRef: ElementRef) {}
}

It is worth noting that you'd want an event emitter which communicates changes in track-scroll directive back to the parent component.

Now as indicated in the previous posting on implementing in the parent component html you'd modify the tag with a on notify event handler:

<nav track-scroll (notify)='onNotify($event)' >
   <nav class='backgroundimageclass' style.background-image.position-y = "{{this.scrollpos}}px"
</nav>


Now in your parent component you'd need to make sure to have  scrollpos set as class instance object type number and ensure that the event function is defined with updates to scrollpos in this onNotify function:

@Component({
    moduleId: module.id,
  selector: 'parentcomponent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css'],

})

export class ParentComponent{
   scrollpos: number = 0.0;

   onNotify(message:number):void {
        this.scrollpos = message*0.2;
        console.log("hitting!");
        console.log(message);
    }
}

Thus the child directive is transmitting back through "message" the scroll position which is assigned to the parent class object scrollpos and this class object is interpolated back into the parent html style.background-image.position-y value...note we are scaling to a fractional value 0.2 the amount of change resembling parallax so that the background image is not equal to the shift in text.

Here is an example parent.component.css sheet for adding the background image:

.backgroundimageclass{
     background-image: url(../assets/MainNavHeader_V01.png);
    /*background: rgba(76, 175, 80, 1.0);*/
    /*background-color: black;*/
    /*background-size: 1200px 780px;*/
    padding-top: 10px;
    background-blend-mode: overlay;
    /*min-width: 1236px;*/
    /*min-height: 298px;*/
    /*width: 1236px;*/
    /*height: 298px;*/
    position: relative;
    left: 50px;
    -webkit-mask-image: -webkit-gradient(linear, left 70%, left bottom, from(rgba(0,0,0,1)), to(rgba(0,0,0,0)));
    /*-webkit-mask-image: -webkit-gradient(linear, left 30%, left top, from(rgba(0,0,0,1)), to(rgba(0,0,0,0)));*/
    /*background-position-y: 100px;*/
    /*background-repeat: no-repeat;*/
    /*overflow: auto;
    clear: both;*/
}

I've included in this case a little webkit alpha mask also on the background image which feather fades the bottom border for instance.

Note my import statement above is done so assuming the parent and child directive are in the same file.  If you wanted to separate these, just make sure to update your import statements.

Please read my previous post for additional information on implementing the child directive in the parent.  Namely, you'll want to ensure that the directive is actually done through the app.module.ts declarations for most current versions of Angular 2.0

No comments:

Post a Comment

Oblivion

 Between the fascination of an upcoming pandemic ridden college football season, Taylor Swift, and Kim Kardashian, wildfires, crazier weathe...