primeng
Version:
PrimeNG is an open source UI library for Angular featuring a rich set of 80+ components, a theme designer, various theme alternatives such as Material, Bootstrap, Tailwind, premium templates and professional support. In addition, it integrates with PrimeB
182 lines (178 loc) • 7.21 kB
JavaScript
import { isPlatformBrowser } from '@angular/common';
import * as i0 from '@angular/core';
import { numberAttribute, booleanAttribute, Directive, Input, NgModule } from '@angular/core';
import { removeClass, addClass } from '@primeuix/utils';
import { BaseComponent } from 'primeng/basecomponent';
/**
* AnimateOnScroll is used to apply animations to elements when entering or leaving the viewport during scrolling.
* @group Components
*/
class AnimateOnScroll extends BaseComponent {
/**
* Selector to define the CSS class for enter animation.
* @group Props
*/
enterClass;
/**
* Selector to define the CSS class for leave animation.
* @group Props
*/
leaveClass;
/**
* Specifies the root option of the IntersectionObserver API.
* @group Props
*/
root;
/**
* Specifies the rootMargin option of the IntersectionObserver API.
* @group Props
*/
rootMargin;
/**
* Specifies the threshold option of the IntersectionObserver API
* @group Props
*/
threshold;
/**
* Whether the scroll event listener should be removed after initial run.
* @group Props
*/
once = true;
observer;
resetObserver;
isObserverActive = false;
animationState;
animationEndListener;
ngOnInit() {
super.ngOnInit();
if (isPlatformBrowser(this.platformId)) {
this.renderer.setStyle(this.el.nativeElement, 'opacity', this.enterClass ? '0' : '');
}
}
ngAfterViewInit() {
super.ngAfterViewInit();
if (isPlatformBrowser(this.platformId)) {
this.bindIntersectionObserver();
}
}
get options() {
return {
root: this.root,
rootMargin: this.rootMargin,
threshold: this.threshold
};
}
bindIntersectionObserver() {
this.observer = new IntersectionObserver(([entry]) => {
if (this.isObserverActive) {
if (entry.boundingClientRect.top > 0) {
entry.isIntersecting ? this.enter() : this.leave();
}
}
else if (entry.isIntersecting) {
this.enter();
}
this.isObserverActive = true;
}, this.options);
setTimeout(() => this.observer.observe(this.el.nativeElement), 0);
// Reset
this.resetObserver = new IntersectionObserver(([entry]) => {
if (entry.boundingClientRect.top > 0 && !entry.isIntersecting) {
this.el.nativeElement.style.opacity = this.enterClass ? '0' : '';
removeClass(this.el.nativeElement, [this.enterClass, this.leaveClass]);
this.resetObserver.unobserve(this.el.nativeElement);
}
this.animationState = undefined;
}, { ...this.options, threshold: 0 });
}
enter() {
if (this.animationState !== 'enter' && this.enterClass) {
this.el.nativeElement.style.opacity = '';
removeClass(this.el.nativeElement, this.leaveClass);
addClass(this.el.nativeElement, this.enterClass);
this.once && this.unbindIntersectionObserver();
this.bindAnimationEvents();
this.animationState = 'enter';
}
}
leave() {
if (this.animationState !== 'leave' && this.leaveClass) {
this.el.nativeElement.style.opacity = this.enterClass ? '0' : '';
removeClass(this.el.nativeElement, this.enterClass);
addClass(this.el.nativeElement, this.leaveClass);
this.bindAnimationEvents();
this.animationState = 'leave';
}
}
bindAnimationEvents() {
if (!this.animationEndListener) {
this.animationEndListener = this.renderer.listen(this.el.nativeElement, 'animationend', () => {
removeClass(this.el.nativeElement, [this.enterClass, this.leaveClass]);
!this.once && this.resetObserver.observe(this.el.nativeElement);
this.unbindAnimationEvents();
});
}
}
unbindAnimationEvents() {
if (this.animationEndListener) {
this.animationEndListener();
this.animationEndListener = null;
}
}
unbindIntersectionObserver() {
this.observer?.unobserve(this.el.nativeElement);
this.resetObserver?.unobserve(this.el.nativeElement);
this.isObserverActive = false;
}
ngOnDestroy() {
this.unbindAnimationEvents();
this.unbindIntersectionObserver();
super.ngOnDestroy();
}
static ɵfac = /*@__PURE__*/ (() => { let ɵAnimateOnScroll_BaseFactory; return function AnimateOnScroll_Factory(__ngFactoryType__) { return (ɵAnimateOnScroll_BaseFactory || (ɵAnimateOnScroll_BaseFactory = i0.ɵɵgetInheritedFactory(AnimateOnScroll)))(__ngFactoryType__ || AnimateOnScroll); }; })();
static ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: AnimateOnScroll, selectors: [["", "pAnimateOnScroll", ""]], hostVars: 2, hostBindings: function AnimateOnScroll_HostBindings(rf, ctx) { if (rf & 2) {
i0.ɵɵclassProp("p-animateonscroll", true);
} }, inputs: { enterClass: "enterClass", leaveClass: "leaveClass", root: "root", rootMargin: "rootMargin", threshold: [2, "threshold", "threshold", numberAttribute], once: [2, "once", "once", booleanAttribute] }, features: [i0.ɵɵInputTransformsFeature, i0.ɵɵInheritDefinitionFeature] });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AnimateOnScroll, [{
type: Directive,
args: [{
selector: '[pAnimateOnScroll]',
standalone: true,
host: {
'[class.p-animateonscroll]': 'true'
}
}]
}], null, { enterClass: [{
type: Input
}], leaveClass: [{
type: Input
}], root: [{
type: Input
}], rootMargin: [{
type: Input
}], threshold: [{
type: Input,
args: [{ transform: numberAttribute }]
}], once: [{
type: Input,
args: [{ transform: booleanAttribute }]
}] }); })();
class AnimateOnScrollModule {
static ɵfac = function AnimateOnScrollModule_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || AnimateOnScrollModule)(); };
static ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: AnimateOnScrollModule });
static ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({});
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AnimateOnScrollModule, [{
type: NgModule,
args: [{
imports: [AnimateOnScroll],
exports: [AnimateOnScroll]
}]
}], null, null); })();
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(AnimateOnScrollModule, { imports: [AnimateOnScroll], exports: [AnimateOnScroll] }); })();
/**
* Generated bundle index. Do not edit.
*/
export { AnimateOnScroll, AnimateOnScrollModule };
//# sourceMappingURL=primeng-animateonscroll.mjs.map