Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | 2x 2x 2x 6x 6x 6x 6x 6x 6x 6x 6x 1x 1x 1x 1x 7x 2x 2x 1x 1x 1x 1x 3x 1x 2x 1x 1x 1x 1x 1x 1x 1x | import {
Component,
ContentChild,
ElementRef,
EventEmitter,
Inject,
Input,
OnDestroy,
OnInit,
Output,
PLATFORM_ID,
TemplateRef
} from '@angular/core';
import {isPlatformBrowser} from '@angular/common';
/**
An element that listens to viewport positioning and fires inView and notInview events
### Example
```html
<ngui-inview [observerOptions]="myObserverOptions" (inview)="doA()" (notInview)="doB()">
<img *ngIf src="https://picsum.photos/800/300?image=1>
</ngui-inview>
```
*/
@Component({
selector: 'ngui-inview',
template: `
<ng-container *ngIf="isInview" [ngTemplateOutlet]="template">
</ng-container>
`,
styles: [':host {display: block;}']
})
export class NguiInviewComponent implements OnInit, OnDestroy {
/** <ng-template> reference */
@ContentChild(TemplateRef, {static: true}) template: TemplateRef<any>;
/** IntersectionObserver options */
@Input() observerOptions: IntersectionObserverInit = {threshold: [.1, .2, .3, .4, .5, .6, .7, .8]};
/** Deprecated config. Use `observerOptions` instead.
* @deprecated Use `observerOptions` instead. */
@Input() options: any;
/** Controls whether blur effect is applied to a component with less than 80% intersection ratio.
* Only applies when there are no "inview" event handlers defined.
**/
@Input() blurEnabled = true;
@Output() inview: EventEmitter<IntersectionObserverEntry> = new EventEmitter();
@Output() notInview: EventEmitter<IntersectionObserverEntry> = new EventEmitter();
observer: IntersectionObserver;
/** indicates that this element is in viewport */
isInview = false;
/** indicates that this element is 80% in viewport. Used by the default callback */
once80PctVisible = false;
constructor(
private element: ElementRef,
@Inject(PLATFORM_ID) private platformId: any) {
}
/** Starts IntersectionObserver */
ngOnInit(): void {
Iif (this.options) {
this.observerOptions = this.options;
}
if (isPlatformBrowser(this.platformId)) {
this.observer = new IntersectionObserver(this.handleIntersect.bind(this), this.observerOptions);
this.observer.observe(this.element.nativeElement);
}
}
/** stop IntersectionObserver */
ngOnDestroy(): void {
this.observer.disconnect();
}
/** fires (inview) and (notInview) events when this component is visible or not visible */
handleIntersect(entries): void {
entries.forEach((entry: IntersectionObserverEntry) => {
if (entry['isIntersecting']) {
this.isInview = true;
this.defaultInviewHandler(entry);
this.inview.emit(entry);
} else {
this.notInview.emit(entry);
}
});
}
/**
* default intersection handler, which sets blur dependes on intersection ratio
* this won't be invoked if user provides any (inview) event. e.g. (inview)="something()"
*/
defaultInviewHandler(entry): any {
if (!this.blurEnabled || this.once80PctVisible || this.inview.observers.length) {
return;
}
if (entry.intersectionRatio < 0.8) {
const opacity = entry.intersectionRatio * (1 / 0.8);
const blur = 20 - Math.floor(entry.intersectionRatio * 10) * 4;
const filter = `blur(${blur}px)`;
Object.assign(entry.target.style, {opacity, filter});
} else {
entry.target.style.opacity = 1;
entry.target.style.filter = 'unset';
this.once80PctVisible = true;
}
}
}
|