Skip to content

Instantly share code, notes, and snippets.

@piyushchauhan2011
Forked from amcdnl/VisibilityObserver.js
Created August 4, 2017 03:39
Show Gist options
  • Save piyushchauhan2011/8e8035064ef66414608dc9ec9a95f3ed to your computer and use it in GitHub Desktop.
Save piyushchauhan2011/8e8035064ef66414608dc9ec9a95f3ed to your computer and use it in GitHub Desktop.
import { EventEmitter } from 'angular2/core.js';
/**
* Visibility Observer leveraging new IntersectionObserver API
* Idea from: https://github.com/WICG/IntersectionObserver
*/
export class VisibilityObserver {
onVisible = new EventEmitter();
constructor(element) {
if(window.IntersectionObserver) {
this.observer = new IntersectionObserver(
::this.processChanges, { threshold: [0.5] });
this.observer.observe(element);
}
}
isVisible(boundingClientRect, intersectionRect) {
return ((intersectionRect.width * intersectionRect.height) /
(boundingClientRect.width * boundingClientRect.height) >= 0.5);
}
visibleTimerCallback(element, observer) {
delete element.visibleTimeout;
// Process any pending observations
this.processChanges(observer.takeRecords());
if ('isVisible' in element) {
delete element.isVisible;
this.onVisible.emit();
observer.unobserve(element);
}
}
processChanges(changes) {
changes.forEach((changeRecord) => {
var element = changeRecord.target;
element.isVisible = this.isVisible(changeRecord.boundingClientRect, changeRecord.intersectionRect);
if ('isVisible' in element) {
// Transitioned from hidden to visible
element.visibleTimeout = setTimeout(::this.visibleTimerCallback, 1000, element, this.observer);
} else {
// Transitioned from visible to hidden
if ('visibleTimeout' in element) {
clearTimeout(element.visibleTimeout);
delete element.visibleTimeout;
}
}
});
}
}
import { Directive, Output, EventEmitter, ElementRef } from 'angular2/core.js';
import { VisibilityObserver } from './VisibilityObserver.js';
@Directive({ selector: '[visibility-observer]' })
export class VisibilityObserverDirective {
@Output()
onVisible = new EventEmitter();
constructor(element: ElementRef) {
new VisibilityObserver(element.nativeElement)
.onVisible.subscribe(::this.visbilityChange)
}
visbilityChange() {
this.onVisible.emit(true);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment