Skip to content

Instantly share code, notes, and snippets.

@awojtczyk
Created September 13, 2016 20:58
Show Gist options
  • Save awojtczyk/389053e64effa28a3d58e0531865e8e7 to your computer and use it in GitHub Desktop.
Save awojtczyk/389053e64effa28a3d58e0531865e8e7 to your computer and use it in GitHub Desktop.
Elastic Header Ionic2
import {Directive, ElementRef} from 'angular2/core';
import {Subject} from "rxjs/Subject";
import {Content, IonicApp} from "ionic-angular/index";
/*
* WIP mashup of
* http://www.joshmorony.com/how-to-create-a-directive-in-ionic-2-parallax-header/
* and ionic2 infinite scroll techniques to access properties
* and http://codepen.io/kaemak/pen/mHyKa
* to get desired behaviour on scroll up/down
*/
@Directive({
selector: '[elastic-header]'
})
export class ElasticHeader {
/*
* more to come
* http://codepen.io/kaemak/pen/mHyKa
* and here last answer shows also transparent option
* http://stackoverflow.com/questions/31290424/hide-fixed-header-on-scroll-down-show-on-scroll-up-and-hover-version-2-please
*/
public scrollerHandle;
public header : HTMLElement;
public delta = 5;
private headerHeight;
private translateAmt;
private scaleAmt;
private scrollTop;
private lastScrollTop = 0;
private ticking;
private content: Content;
scrollSubject = new Subject();
constructor(public element: ElementRef, private app: IonicApp) {
console.log('initializing ElasticHeader');
this.element = element;
this.scrollSubject.debounceTime(200).subscribe(() => {
this.hasScrolled();
});
}
ngAfterViewInit() {
this.content = this.app.getComponent('xyz22');
}
ngOnInit() {
var me = this;
console.log('ngoninit ElasticHeader', arguments);
this.scrollerHandle = this.element.nativeElement.children[0];
this.header = document.getElementById("elastic-header");
this.headerHeight = this.scrollerHandle.clientHeight;
this.translateAmt = null;
this.scaleAmt = null;
this.scrollTop = null;
this.lastScrollTop = null;
this.ticking = false;
this.header.style.webkitTransformOrigin = 'center bottom';
window.addEventListener('resize', () => {
this.headerHeight = this.scrollerHandle.clientHeight;
}, false);
this.scrollerHandle.addEventListener('scroll', () => {
this.scrollSubject.next({});
// if(!me.ticking){
// window.requestAnimationFrame(() => {
// me.updateElasticHeader();
// });
// }
// this.ticking = true;
});
}
updateElasticHeader() {
console.log('updating ElasticHeader');
this.scrollTop = this.scrollerHandle.scrollTop;
if (this.scrollTop >= 0) {
this.translateAmt = this.scrollTop / 2;
this.scaleAmt = 1;
} else {
this.translateAmt = 0;
this.scaleAmt = -this.scrollTop / this.headerHeight + 1;
}
this.header.style.webkitTransform = 'translate3d(0,'+this.translateAmt+'px,0) scale('+this.scaleAmt+','+this.scaleAmt+')';
this.ticking = false;
}
hasScrolled() {
this.scrollTop = this.content.getContentDimensions().scrollTop;
console.log('called hasScrolled ElasticHeader', this.scrollTop);
// Make sure they scroll more than delta
if(Math.abs(this.lastScrollTop - this.scrollTop) <= this.delta)
return;
console.log('hasScrolled delta', Math.abs(this.lastScrollTop - this.scrollTop));
// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (this.scrollTop > this.lastScrollTop) { // && this.scrollTop > this.header.clientHeight) {
// Scroll Down
this.header.classList.remove('nav-down');
this.header.classList.add('nav-up');
} else {
// Scroll Up
// if(this.scrollTop + (<Window>window).innerHeight < window.document.documentElement.clientHeight) {
this.header.classList.remove('nav-up');
this.header.classList.add('nav-down');
// }
}
this.lastScrollTop = this.scrollTop;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment