@ngfly/carousel
Version:
A smooth, customizable carousel component for Angular 17+ applications
89 lines • 9.96 kB
JavaScript
import { Directive, Input } from '@angular/core';
import * as i0 from "@angular/core";
/**
* LazyLoadDirective
*
* A directive for lazy loading images in a carousel component.
* Uses Intersection Observer API to detect when images enter the viewport.
*/
export class LazyLoadDirective {
constructor(el, renderer) {
this.el = el;
this.renderer = renderer;
this.carouselLazyLoad = '';
this.errorImage = 'assets/images/no-image.png';
this.isLoaded = false;
}
/**
* Initialize the directive and set up the Intersection Observer
*/
ngOnInit() {
// Skip if already loaded or no image URL provided
if (this.isLoaded || !this.carouselLazyLoad) {
return;
}
// Check if IntersectionObserver is supported
if ('IntersectionObserver' in window) {
this.observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.loadImage();
this.observer?.unobserve(this.el.nativeElement);
}
});
});
this.observer.observe(this.el.nativeElement);
}
else {
// Fallback for browsers that don't support IntersectionObserver
this.loadImage();
}
}
/**
* Clean up the observer when directive is destroyed
*/
ngOnDestroy() {
// Clean up the observer when directive is destroyed
if (this.observer) {
this.observer.disconnect();
this.observer = undefined;
}
}
/**
* Load the image by setting the src attribute
*/
loadImage() {
this.isLoaded = true;
const element = this.el.nativeElement;
const isImgElement = element.tagName === 'IMG';
if (isImgElement) {
// Handle <img> elements
this.renderer.setAttribute(element, 'src', this.carouselLazyLoad);
// Handle errors
const errorHandler = () => {
this.renderer.setAttribute(element, 'src', this.errorImage);
const unlistenFn = this.renderer.listen(element, 'error', errorHandler);
unlistenFn();
};
this.renderer.listen(element, 'error', errorHandler);
}
else {
// Handle non-image elements with background image
this.renderer.setStyle(element, 'background-image', `url('${this.carouselLazyLoad}')`);
}
}
}
LazyLoadDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LazyLoadDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
LazyLoadDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: LazyLoadDirective, isStandalone: true, selector: "[carouselLazyLoad]", inputs: { carouselLazyLoad: "carouselLazyLoad", errorImage: "errorImage" }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LazyLoadDirective, decorators: [{
type: Directive,
args: [{
selector: '[carouselLazyLoad]',
standalone: true
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { carouselLazyLoad: [{
type: Input
}], errorImage: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF6eS1sb2FkLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvZGlyZWN0aXZlcy9sYXp5LWxvYWQuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWMsS0FBSyxFQUFnQyxNQUFNLGVBQWUsQ0FBQzs7QUFFM0Y7Ozs7O0dBS0c7QUFLSCxNQUFNLE9BQU8saUJBQWlCO0lBTzVCLFlBQ1UsRUFBYyxFQUNkLFFBQW1CO1FBRG5CLE9BQUUsR0FBRixFQUFFLENBQVk7UUFDZCxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBUnBCLHFCQUFnQixHQUFXLEVBQUUsQ0FBQztRQUM5QixlQUFVLEdBQVcsNEJBQTRCLENBQUM7UUFHbkQsYUFBUSxHQUFHLEtBQUssQ0FBQztJQUt0QixDQUFDO0lBRUo7O09BRUc7SUFDSCxRQUFRO1FBQ04sa0RBQWtEO1FBQ2xELElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUMzQyxPQUFPO1NBQ1I7UUFFRCw2Q0FBNkM7UUFDN0MsSUFBSSxzQkFBc0IsSUFBSSxNQUFNLEVBQUU7WUFDcEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNqRCxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFO29CQUN0QixJQUFJLEtBQUssQ0FBQyxjQUFjLEVBQUU7d0JBQ3hCLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQzt3QkFDakIsSUFBSSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsQ0FBQztxQkFDakQ7Z0JBQ0gsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLENBQUM7U0FDOUM7YUFBTTtZQUNMLGdFQUFnRTtZQUNoRSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7U0FDbEI7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxXQUFXO1FBQ1Qsb0RBQW9EO1FBQ3BELElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNqQixJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDO1NBQzNCO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ssU0FBUztRQUNmLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBRXJCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDO1FBQ3RDLE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxPQUFPLEtBQUssS0FBSyxDQUFDO1FBRS9DLElBQUksWUFBWSxFQUFFO1lBQ2hCLHdCQUF3QjtZQUN4QixJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBRWxFLGdCQUFnQjtZQUNoQixNQUFNLFlBQVksR0FBRyxHQUFHLEVBQUU7Z0JBQ3hCLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUM1RCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFlBQVksQ0FBQyxDQUFDO2dCQUN4RSxVQUFVLEVBQUUsQ0FBQztZQUNmLENBQUMsQ0FBQztZQUVGLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsWUFBWSxDQUFDLENBQUM7U0FDdEQ7YUFBTTtZQUNMLGtEQUFrRDtZQUNsRCxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FDcEIsT0FBTyxFQUNQLGtCQUFrQixFQUNsQixRQUFRLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxDQUNsQyxDQUFDO1NBQ0g7SUFDSCxDQUFDOzs4R0EvRVUsaUJBQWlCO2tHQUFqQixpQkFBaUI7MkZBQWpCLGlCQUFpQjtrQkFKN0IsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsb0JBQW9CO29CQUM5QixVQUFVLEVBQUUsSUFBSTtpQkFDakI7eUhBRVUsZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgUmVuZGVyZXIyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8qKlxuICogTGF6eUxvYWREaXJlY3RpdmVcbiAqIFxuICogQSBkaXJlY3RpdmUgZm9yIGxhenkgbG9hZGluZyBpbWFnZXMgaW4gYSBjYXJvdXNlbCBjb21wb25lbnQuXG4gKiBVc2VzIEludGVyc2VjdGlvbiBPYnNlcnZlciBBUEkgdG8gZGV0ZWN0IHdoZW4gaW1hZ2VzIGVudGVyIHRoZSB2aWV3cG9ydC5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2Nhcm91c2VsTGF6eUxvYWRdJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZVxufSlcbmV4cG9ydCBjbGFzcyBMYXp5TG9hZERpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgQElucHV0KCkgY2Fyb3VzZWxMYXp5TG9hZDogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIGVycm9ySW1hZ2U6IHN0cmluZyA9ICdhc3NldHMvaW1hZ2VzL25vLWltYWdlLnBuZyc7XG4gIFxuICBwcml2YXRlIG9ic2VydmVyOiBJbnRlcnNlY3Rpb25PYnNlcnZlciB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBpc0xvYWRlZCA9IGZhbHNlO1xuICBcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBlbDogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjJcbiAgKSB7fVxuICBcbiAgLyoqXG4gICAqIEluaXRpYWxpemUgdGhlIGRpcmVjdGl2ZSBhbmQgc2V0IHVwIHRoZSBJbnRlcnNlY3Rpb24gT2JzZXJ2ZXJcbiAgICovXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIFNraXAgaWYgYWxyZWFkeSBsb2FkZWQgb3Igbm8gaW1hZ2UgVVJMIHByb3ZpZGVkXG4gICAgaWYgKHRoaXMuaXNMb2FkZWQgfHwgIXRoaXMuY2Fyb3VzZWxMYXp5TG9hZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBcbiAgICAvLyBDaGVjayBpZiBJbnRlcnNlY3Rpb25PYnNlcnZlciBpcyBzdXBwb3J0ZWRcbiAgICBpZiAoJ0ludGVyc2VjdGlvbk9ic2VydmVyJyBpbiB3aW5kb3cpIHtcbiAgICAgIHRoaXMub2JzZXJ2ZXIgPSBuZXcgSW50ZXJzZWN0aW9uT2JzZXJ2ZXIoZW50cmllcyA9PiB7XG4gICAgICAgIGVudHJpZXMuZm9yRWFjaChlbnRyeSA9PiB7XG4gICAgICAgICAgaWYgKGVudHJ5LmlzSW50ZXJzZWN0aW5nKSB7XG4gICAgICAgICAgICB0aGlzLmxvYWRJbWFnZSgpO1xuICAgICAgICAgICAgdGhpcy5vYnNlcnZlcj8udW5vYnNlcnZlKHRoaXMuZWwubmF0aXZlRWxlbWVudCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgXG4gICAgICB0aGlzLm9ic2VydmVyLm9ic2VydmUodGhpcy5lbC5uYXRpdmVFbGVtZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRmFsbGJhY2sgZm9yIGJyb3dzZXJzIHRoYXQgZG9uJ3Qgc3VwcG9ydCBJbnRlcnNlY3Rpb25PYnNlcnZlclxuICAgICAgdGhpcy5sb2FkSW1hZ2UoKTtcbiAgICB9XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBDbGVhbiB1cCB0aGUgb2JzZXJ2ZXIgd2hlbiBkaXJlY3RpdmUgaXMgZGVzdHJveWVkXG4gICAqL1xuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAvLyBDbGVhbiB1cCB0aGUgb2JzZXJ2ZXIgd2hlbiBkaXJlY3RpdmUgaXMgZGVzdHJveWVkXG4gICAgaWYgKHRoaXMub2JzZXJ2ZXIpIHtcbiAgICAgIHRoaXMub2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgdGhpcy5vYnNlcnZlciA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBMb2FkIHRoZSBpbWFnZSBieSBzZXR0aW5nIHRoZSBzcmMgYXR0cmlidXRlXG4gICAqL1xuICBwcml2YXRlIGxvYWRJbWFnZSgpOiB2b2lkIHtcbiAgICB0aGlzLmlzTG9hZGVkID0gdHJ1ZTtcbiAgICBcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5lbC5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IGlzSW1nRWxlbWVudCA9IGVsZW1lbnQudGFnTmFtZSA9PT0gJ0lNRyc7XG4gICAgXG4gICAgaWYgKGlzSW1nRWxlbWVudCkge1xuICAgICAgLy8gSGFuZGxlIDxpbWc+IGVsZW1lbnRzXG4gICAgICB0aGlzLnJlbmRlcmVyLnNldEF0dHJpYnV0ZShlbGVtZW50LCAnc3JjJywgdGhpcy5jYXJvdXNlbExhenlMb2FkKTtcbiAgICAgIFxuICAgICAgLy8gSGFuZGxlIGVycm9yc1xuICAgICAgY29uc3QgZXJyb3JIYW5kbGVyID0gKCkgPT4ge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldEF0dHJpYnV0ZShlbGVtZW50LCAnc3JjJywgdGhpcy5lcnJvckltYWdlKTtcbiAgICAgICAgY29uc3QgdW5saXN0ZW5GbiA9IHRoaXMucmVuZGVyZXIubGlzdGVuKGVsZW1lbnQsICdlcnJvcicsIGVycm9ySGFuZGxlcik7XG4gICAgICAgIHVubGlzdGVuRm4oKTtcbiAgICAgIH07XG4gICAgICBcbiAgICAgIHRoaXMucmVuZGVyZXIubGlzdGVuKGVsZW1lbnQsICdlcnJvcicsIGVycm9ySGFuZGxlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEhhbmRsZSBub24taW1hZ2UgZWxlbWVudHMgd2l0aCBiYWNrZ3JvdW5kIGltYWdlXG4gICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKFxuICAgICAgICBlbGVtZW50LFxuICAgICAgICAnYmFja2dyb3VuZC1pbWFnZScsXG4gICAgICAgIGB1cmwoJyR7dGhpcy5jYXJvdXNlbExhenlMb2FkfScpYFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn0iXX0=