rm-image-slider
Version:
Angular image slider and carousel component with lightbox popup, video support (YouTube MP4), touch gestures, lazy loading, responsive design, and accessibility (WCAG). Lightweight, standalone, tree-shakable Angular library.
1 lines • 73.4 kB
Source Map (JSON)
{"version":3,"file":"rm-image-slider.mjs","sources":["../../../projects/rm-image-slider/src/lib/rm-image-slider.service.ts","../../../projects/rm-image-slider/src/lib/slider-custom-image/slider-custom-image.component.ts","../../../projects/rm-image-slider/src/lib/slider-custom-image/slider-custom-image.component.html","../../../projects/rm-image-slider/src/lib/slider-lightbox/slider-lightbox.component.ts","../../../projects/rm-image-slider/src/lib/slider-lightbox/slider-lightbox.component.html","../../../projects/rm-image-slider/src/lib/rm-image-slider.component.ts","../../../projects/rm-image-slider/src/lib/rm-image-slider.component.html","../../../projects/rm-image-slider/src/public-api.ts","../../../projects/rm-image-slider/src/rm-image-slider.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\n\r\nconst DESC = 'DESC',\r\n ASC = 'ASC';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class RmImageSliderService {\r\n constructor() {}\r\n\r\n isBase64(str: string) {\r\n var base64regex =\r\n /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;\r\n return base64regex.test(str);\r\n }\r\n\r\n base64FileExtension(str: string) {\r\n return str.substring('data:image/'.length, str.indexOf(';base64'));\r\n }\r\n\r\n // orderArray(arr = [], orderType = ASC) {\r\n // if (arr?.length && orderType) {\r\n // return arr.sort((ob1: any, ob2: any) => {\r\n // if (ob1['order'] === null || !ob1['order']) {\r\n // return 1;\r\n // } else if (ob2['order'] === null || !ob2['order']) {\r\n // return -1;\r\n // } else if (ob1['order'] > ob2['order']) {\r\n // if (orderType === DESC) {\r\n // return -1;\r\n // } else {\r\n // return 1;\r\n // }\r\n // } else if (ob1['order'] < ob2['order']) {\r\n // if (orderType === DESC) {\r\n // return 1;\r\n // } else {\r\n // return -1;\r\n // }\r\n // }\r\n // });\r\n // }\r\n // return arr;\r\n // }\r\n\r\n orderArray(arr = [], orderType = ASC) {\r\n if (arr?.length && orderType) {\r\n return arr.sort((ob1: any, ob2: any) => {\r\n // Handle potential undefined 'order' properties\r\n const order1 = ob1['order'];\r\n const order2 = ob2['order'];\r\n\r\n // Ensure consistent sorting for undefined/null 'order' values\r\n if (order1 === null || order1 === undefined) {\r\n return 1; // Place elements with undefined or null 'order' at the end\r\n } else if (order2 === null || order2 === undefined) {\r\n return -1; // Place elements with undefined or null 'order' at the beginning\r\n } else {\r\n // Apply ascending or descending order based on 'orderType'\r\n return orderType === DESC\r\n ? order2 - order1 // Reverse for descending order\r\n : order1 - order2; // Maintain for ascending order\r\n }\r\n });\r\n }\r\n\r\n return arr; // Return the original array if conditions are not met\r\n }\r\n}\r\n","import {\n Component,\n Input,\n OnChanges,\n SimpleChanges,\n Inject,\n DOCUMENT,\n ChangeDetectionStrategy\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';\r\nimport { RmImageSliderService } from './../rm-image-slider.service';\r\n\r\nconst youtubeRegExp =\r\n /^.*(youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=|\\&v=|\\?v=)([^#\\&\\?]*).*/,\r\n validFileExtensions = ['jpeg', 'jpg', 'gif', 'png'],\r\n validVideoExtensions = ['mp4'];\r\n\r\n@Component({\r\n selector: 'custom-img',\r\n imports: [CommonModule],\r\n templateUrl: './slider-custom-image.component.html',\r\n changeDetection: ChangeDetectionStrategy.Eager,\n styleUrl: './slider-custom-image.component.css'\r\n})\r\nexport class SliderCustomImageComponent implements OnChanges {\r\n YOUTUBE = 'youtube';\r\n IMAGE = 'image';\r\n VIDEO = 'video';\r\n fileUrl: SafeResourceUrl = '';\r\n fileExtension = '';\r\n type = this.IMAGE;\r\n imageLoading: boolean = true;\r\n\r\n // @inputs\r\n @Input() showVideo: boolean = false;\r\n @Input() videoAutoPlay: boolean = false;\r\n @Input() showVideoControls: number = 1;\r\n @Input() currentImageIndex!: number;\r\n @Input() imageIndex!: number;\r\n @Input() speed: number = 1;\r\n @Input() imageUrl: any;\r\n @Input() isVideo = false;\r\n @Input() alt: String = '';\r\n @Input() title: String = '';\r\n @Input() direction: string = 'ltr';\r\n @Input() ratio: boolean = false;\r\n @Input() lazy: boolean = false;\r\n\r\n constructor(\r\n public imageSliderService: RmImageSliderService,\r\n private sanitizer: DomSanitizer,\r\n @Inject(DOCUMENT) document: Document\r\n ) {}\r\n\r\n ngOnChanges(changes: SimpleChanges) {\r\n if (\r\n this['imageUrl'] &&\r\n typeof this['imageUrl'] === 'string' &&\r\n ((changes['imageUrl'] && changes['imageUrl'].firstChange) ||\r\n this.videoAutoPlay)\r\n ) {\r\n this.setUrl();\r\n }\r\n }\r\n\r\n setUrl() {\r\n const url = this.imageUrl;\r\n this.imageLoading = true;\r\n this.fileUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url);\r\n this.fileExtension = url.split('.').pop().split(/\\#|\\?/)[0];\r\n if (\r\n this.imageSliderService.base64FileExtension(url) &&\r\n (validFileExtensions.indexOf(\r\n this.imageSliderService.base64FileExtension(url).toLowerCase()\r\n ) > -1 ||\r\n validVideoExtensions.indexOf(\r\n this.imageSliderService.base64FileExtension(url).toLowerCase()\r\n ) > -1)\r\n ) {\r\n this.fileExtension = this.imageSliderService.base64FileExtension(url);\r\n }\r\n // verify for youtube url\r\n const match = url.match(youtubeRegExp);\r\n if (match && match[2].length === 11) {\r\n if (this.showVideo) {\r\n this.type = this.YOUTUBE;\r\n this.fileUrl = this.sanitizer.bypassSecurityTrustResourceUrl(\r\n `${'https://www.youtube.com/embed/'}${match[2]}${\r\n this.videoAutoPlay\r\n ? '?autoplay=1&enablejsapi=1'\r\n : '?autoplay=0&enablejsapi=1'\r\n }${'&controls='}${this.showVideoControls}`\r\n );\r\n } else {\r\n this.type = this.IMAGE;\r\n this.fileUrl = this.sanitizer.bypassSecurityTrustResourceUrl(\r\n `https://img.youtube.com/vi/${match[2]}/0.jpg`\r\n );\r\n }\r\n } else if (\r\n this.fileExtension &&\r\n validFileExtensions.indexOf(this.fileExtension.toLowerCase()) > -1\r\n ) {\r\n this.type = this.IMAGE;\r\n } else if (\r\n this.fileExtension &&\r\n validVideoExtensions.indexOf(this.fileExtension.toLowerCase()) > -1\r\n ) {\r\n this.type = this.VIDEO;\r\n if (\r\n this.videoAutoPlay &&\r\n document.getElementById(`video_${this.imageIndex}`)\r\n ) {\r\n const videoObj: any = document.getElementById(\r\n `video_${this.imageIndex}`\r\n );\r\n setTimeout(() => {\r\n videoObj.play();\r\n }, this.speed * 1000);\r\n }\r\n }\r\n }\r\n\r\n videoClickHandler(event: any) {\r\n if (event && event.srcElement && !this.showVideoControls) {\r\n if (event.srcElement.paused) {\r\n event.srcElement.play();\r\n } else {\r\n event.srcElement.pause();\r\n }\r\n }\r\n }\r\n}\r\n","@if (fileUrl) {\r\n <div class=\"custom-image-main\" [ngClass]=\"{'ng-fullimage-loading': imageLoading}\">\r\n @if (type === IMAGE && fileUrl) {\r\n <img class=\"image\" (load)=\"imageLoading = false\" [ngClass]=\"{'ratio': ratio}\"\r\n [src]=\"fileUrl\" [alt]=\"alt\" [title]=\"title\" [attr.loading]=\"lazy == true ? 'lazy' : null\">\r\n }\r\n @if (type === YOUTUBE && fileUrl) {\r\n <iframe class=\"youtube\" [src]=\"fileUrl\"\r\n [attr.loading]=\"lazy == true ? 'lazy' : null\" frameborder=\"0\" allow=\"autoplay\" allowfullscreen></iframe>\r\n }\r\n @if (type === VIDEO) {\r\n <video class=\"video\" [id]=\"'video_' + imageIndex\" [ngClass]=\"{'ratio': ratio}\" (click)=\"videoClickHandler($event)\"\r\n [autoplay]=\"videoAutoPlay\" type=\"video/mp4\"\r\n [attr.controls]=\"showVideoControls ? showVideoControls : null\" controlsList=\"nodownload\">\r\n <source [src]=\"fileUrl\" type=\"video/mp4\">\r\n Your browser does not support the video tag.\r\n </video>\r\n }\r\n @if (!fileUrl) {\r\n <div [dir]=\"direction\" class=\"invalid-msg\">Invalid file format</div>\r\n }\r\n @if (type === YOUTUBE || type === VIDEO || isVideo) {\r\n <span class=\"youtube-icon\"></span>\r\n }\r\n </div>\r\n}","import {\n ChangeDetectorRef,\n Component,\n OnInit,\n OnChanges,\n SimpleChanges,\n Inject,\n AfterViewInit,\n OnDestroy,\n Input,\n Output,\n EventEmitter,\n ViewChild,\n HostListener,\n ElementRef,\n DOCUMENT,\n ChangeDetectionStrategy\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DomSanitizer } from '@angular/platform-browser';\r\nimport { SliderCustomImageComponent } from '../slider-custom-image/slider-custom-image.component';\r\nimport { ImageObject } from '../interface';\r\n\r\nconst LIGHTBOX_NEXT_ARROW_CLICK_MESSAGE = 'lightbox next',\r\n LIGHTBOX_PREV_ARROW_CLICK_MESSAGE = 'lightbox previous';\r\n\r\n@Component({\r\n selector: 'slider-lightbox',\r\n imports: [CommonModule, SliderCustomImageComponent],\r\n templateUrl: './slider-lightbox.component.html',\r\n changeDetection: ChangeDetectionStrategy.Eager,\n styleUrl: './slider-lightbox.component.css'\r\n})\r\nexport class SliderLightboxComponent\r\n implements OnInit, AfterViewInit, OnDestroy\r\n{\r\n totalImages: number = 0;\r\n nextImageIndex: number = -1;\r\n popupWidth: number = 1200;\r\n marginLeft: number = 0;\r\n imageFullscreenView: boolean = false;\r\n lightboxPrevDisable: boolean = false;\r\n lightboxNextDisable: boolean = false;\r\n showLoading: boolean = true;\r\n effectStyle: string = 'none';\r\n speed: number = 1; // default speed in second\r\n title: string = '';\r\n currentImageIndex: number = 0;\r\n\r\n // for swipe event\r\n private swipeLightboxImgCoord?: [number, number];\r\n private swipeLightboxImgTime?: number;\r\n\r\n @ViewChild('lightboxDiv', { static: false }) lightboxDiv!: ElementRef;\r\n @ViewChild('lightboxImageDiv', { static: false })\r\n lightboxImageDiv!: ElementRef;\r\n\r\n // @Inputs\r\n @Input() images: Array<ImageObject> = [];\r\n @Input()\r\n set imageIndex(index: number) {\r\n if (index !== undefined && index > -1 && index < this.images.length) {\r\n this.currentImageIndex = index;\r\n }\r\n this.nextPrevDisable();\r\n }\r\n @Input()\r\n set show(visiableFlag: boolean) {\r\n this.imageFullscreenView = visiableFlag;\r\n this.elRef.nativeElement.ownerDocument.body.style.overflow = '';\r\n if (visiableFlag === true) {\r\n this.elRef.nativeElement.ownerDocument.body.style.overflow = 'hidden';\r\n // this.getImageData();\r\n this.setPopupSliderWidth();\r\n }\r\n }\r\n @Input() videoAutoPlay: boolean = false;\r\n @Input() direction: string = 'ltr';\r\n @Input() paginationShow: boolean = false;\r\n @Input()\r\n set animationSpeed(data: number) {\r\n if (data && typeof data === 'number' && data >= 0.1 && data <= 5) {\r\n this.speed = data;\r\n }\r\n }\r\n @Input() infinite: boolean = false;\r\n @Input() arrowKeyMove: boolean = true;\r\n @Input() showVideoControls: boolean = true;\r\n\r\n // @Output\r\n @Output() close = new EventEmitter<any>();\r\n @Output() prevImage = new EventEmitter<any>();\r\n @Output() nextImage = new EventEmitter<any>();\r\n\r\n @HostListener('window:resize', ['$event'])\r\n onResize(event: any) {\r\n this.effectStyle = 'none';\r\n this.setPopupSliderWidth();\r\n }\r\n @HostListener('document:keyup', ['$event'])\r\n handleKeyboardEvent(event: KeyboardEvent) {\r\n if (event && event.key && this.arrowKeyMove) {\r\n if (event.key.toLowerCase() === 'arrowright') {\r\n this.nextImageLightbox();\r\n }\r\n\r\n if (event.key.toLowerCase() === 'arrowleft') {\r\n this.prevImageLightbox();\r\n }\r\n\r\n if (event.key.toLowerCase() === 'escape') {\r\n this.closeLightbox();\r\n }\r\n }\r\n }\r\n\r\n constructor(\r\n private cdRef: ChangeDetectorRef,\r\n private sanitizer: DomSanitizer,\r\n private elRef: ElementRef,\r\n @Inject(DOCUMENT) private document: any\r\n ) {}\r\n\r\n ngOnInit() {}\r\n\r\n ngAfterViewInit() {}\r\n\r\n ngOnDestroy() {\r\n this.resetState();\r\n }\r\n\r\n setPopupSliderWidth() {\r\n if (window && window.innerWidth) {\r\n this.popupWidth = window.innerWidth;\r\n this.totalImages = this.images.length;\r\n if (\r\n typeof this.currentImageIndex === 'number' &&\r\n this.currentImageIndex !== undefined\r\n ) {\r\n this.marginLeft = -1 * this.popupWidth * this.currentImageIndex;\r\n this.getImageData();\r\n this.nextPrevDisable();\r\n setTimeout(() => {\r\n this.showLoading = false;\r\n }, 500);\r\n }\r\n }\r\n }\r\n\r\n closeLightbox() {\r\n this.close.emit();\r\n }\r\n\r\n prevImageLightbox() {\r\n this.effectStyle = `all ${this.speed}s ease-in-out`;\r\n if (this.currentImageIndex > 0 && !this.lightboxPrevDisable) {\r\n this.currentImageIndex--;\r\n this.prevImage.emit(LIGHTBOX_PREV_ARROW_CLICK_MESSAGE);\r\n this.marginLeft = -1 * this.popupWidth * this.currentImageIndex;\r\n this.getImageData();\r\n this.nextPrevDisable();\r\n }\r\n }\r\n\r\n nextImageLightbox() {\r\n this.effectStyle = `all ${this.speed}s ease-in-out`;\r\n if (\r\n this.currentImageIndex < this.images.length - 1 &&\r\n !this.lightboxNextDisable\r\n ) {\r\n this.currentImageIndex++;\r\n this.nextImage.emit(LIGHTBOX_NEXT_ARROW_CLICK_MESSAGE);\r\n this.marginLeft = -1 * this.popupWidth * this.currentImageIndex;\r\n this.getImageData();\r\n this.nextPrevDisable();\r\n }\r\n }\r\n\r\n nextPrevDisable() {\r\n this.lightboxNextDisable = true;\r\n this.lightboxPrevDisable = true;\r\n setTimeout(() => {\r\n this.applyButtonDisableCondition();\r\n }, this.speed * 1000);\r\n }\r\n\r\n applyButtonDisableCondition() {\r\n this.lightboxNextDisable = false;\r\n this.lightboxPrevDisable = false;\r\n if (!this.infinite && this.currentImageIndex >= this.images.length - 1) {\r\n this.lightboxNextDisable = true;\r\n }\r\n if (!this.infinite && this.currentImageIndex <= 0) {\r\n this.lightboxPrevDisable = true;\r\n }\r\n }\r\n\r\n getImageData() {\r\n if (\r\n this.images &&\r\n this.images.length &&\r\n typeof this.currentImageIndex === 'number' &&\r\n this.currentImageIndex !== undefined &&\r\n this.images[this.currentImageIndex] &&\r\n (this.images[this.currentImageIndex]['image'] ||\r\n this.images[this.currentImageIndex]['video'])\r\n ) {\r\n this.title = this.images[this.currentImageIndex]['title'] || '';\r\n this.totalImages = this.images.length;\r\n for (const iframeI in this.document.getElementsByTagName('iframe')) {\r\n if (\r\n this.document.getElementsByTagName('iframe')[iframeI] &&\r\n this.document.getElementsByTagName('iframe')[iframeI].contentWindow &&\r\n this.document.getElementsByTagName('iframe')[iframeI].contentWindow\r\n .postMessage\r\n ) {\r\n this.document\r\n .getElementsByTagName('iframe')\r\n [iframeI].contentWindow.postMessage(\r\n '{\"event\":\"command\",\"func\":\"pauseVideo\",\"args\":\"\"}',\r\n '*'\r\n );\r\n }\r\n }\r\n for (const videoI in this.document.getElementsByTagName('video')) {\r\n if (\r\n this.document.getElementsByTagName('video')[videoI] &&\r\n this.document.getElementsByTagName('video')[videoI].pause\r\n ) {\r\n this.document.getElementsByTagName('video')[videoI].pause();\r\n }\r\n }\r\n }\r\n }\r\n\r\n resetState() {\r\n this.images = [];\r\n }\r\n\r\n swipeLightboxImg(e: TouchEvent, when: string): void {\r\n const coord: [number, number] = [\r\n e.changedTouches[0].pageX,\r\n e.changedTouches[0].pageY,\r\n ];\r\n const time = new Date().getTime();\r\n\r\n if (when === 'start') {\r\n this.swipeLightboxImgCoord = coord;\r\n this.swipeLightboxImgTime = time;\r\n } else if (\r\n when === 'end' &&\r\n this.swipeLightboxImgCoord &&\r\n this.swipeLightboxImgTime\r\n ) {\r\n const direction = [\r\n coord[0] - this.swipeLightboxImgCoord[0],\r\n coord[1] - this.swipeLightboxImgCoord[1],\r\n ];\r\n const duration = time - this.swipeLightboxImgTime;\r\n\r\n if (\r\n duration < 1000 && //\r\n Math.abs(direction[0]) > 30 && // Long enough\r\n Math.abs(direction[0]) > Math.abs(direction[1] * 3)\r\n ) {\r\n // Horizontal enough\r\n if (direction[0] < 0) {\r\n this.nextImageLightbox();\r\n } else {\r\n this.prevImageLightbox();\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","@if (imageFullscreenView) {\r\n <div class=\"ng-image-fullscreen-view\">\r\n <div class=\"lightbox-wrapper\">\r\n <a class=\"close\" (click)=\"closeLightbox()\"></a>\r\n <div class=\"lightbox-div\" #lightboxDiv>\r\n @if (showLoading) {\r\n <div class=\"pre-loader\">\r\n <div class=\"mnml-spinner\"></div>\r\n </div>\r\n }\r\n <div class=\"lightbox-image-main\"\r\n [ngStyle]=\"{'margin-left': marginLeft + 'px', 'grid-template-columns': 'repeat('+images.length+',1fr)', 'transition': effectStyle}\">\r\n @for (img of images; track img; let i = $index) {\r\n <div class=\"lightbox-image\" [ngStyle]=\"{'width': popupWidth + 'px'}\"\r\n [attr.id]=\"'ng-lightbox-image-' + i\" (touchstart)=\"swipeLightboxImg($event, 'start')\"\r\n (touchend)=\"swipeLightboxImg($event, 'end')\" #lightboxImageDiv>\r\n <div class=\"close-outside\" (click)=\"!img?.video && closeLightbox()\"></div>\r\n <custom-img [imageUrl]=\"img?.image || img?.video\" [isVideo]=\"!!(img?.posterImage || img?.video)\"\r\n [currentImageIndex]=\"currentImageIndex\" [imageIndex]=\"i\" [speed]=\"speed\"\r\n [videoAutoPlay]=\"videoAutoPlay && i == currentImageIndex\" [showVideoControls]=\"showVideoControls ? 1 : 0\"\r\n [alt]=\"img?.alt || img?.title || ''\" [title]=\"img?.title || img?.alt || ''\" [showVideo]=\"true\"\r\n [direction]=\"direction\">\r\n </custom-img>\r\n </div>\r\n }\r\n </div>\r\n <div [dir]=\"direction\" [ngClass]=\"{'show': title, 'hide': !title}\" class=\"caption\">{{ title }}</div>\r\n @if (images.length > 1) {\r\n <a [ngClass]=\"{'disable': lightboxPrevDisable}\" class=\"prev icons prev-icon\"\r\n (click)=\"prevImageLightbox()\">‹</a>\r\n }\r\n @if (images.length > 1) {\r\n <a [ngClass]=\"{'disable': lightboxNextDisable}\" class=\"next icons next-icon\"\r\n (click)=\"nextImageLightbox()\">›</a>\r\n }\r\n </div>\r\n </div>\r\n @if (paginationShow) {\r\n <div class=\"popup-pagination\">{{currentImageIndex + 1}} of {{totalImages}}</div>\r\n }\r\n </div>\r\n}","import {\n ChangeDetectorRef,\n Component,\n OnInit,\n OnChanges,\n DoCheck,\n SimpleChanges,\n SimpleChange,\n AfterViewInit,\n OnDestroy,\n Input,\n Output,\n EventEmitter,\n ViewEncapsulation,\n ViewChild,\n HostListener,\n PLATFORM_ID,\n Inject,\n ElementRef,\n ChangeDetectionStrategy\n} from '@angular/core';\r\n\r\nimport { CommonModule, isPlatformBrowser, isPlatformServer } from '@angular/common';\r\nimport { RmImageSliderService } from './rm-image-slider.service';\r\nimport { SliderLightboxComponent } from './slider-lightbox/slider-lightbox.component';\r\nimport { SliderCustomImageComponent } from './slider-custom-image/slider-custom-image.component';\r\nimport { ImageObject } from './interface';\r\n\r\nconst NEXT_ARROW_CLICK_MESSAGE = 'next',\r\n PREV_ARROW_CLICK_MESSAGE = 'previous';\r\n\r\n@Component({\r\n selector: 'rm-image-slider',\r\n imports: [CommonModule, SliderLightboxComponent, SliderCustomImageComponent],\r\n templateUrl: './rm-image-slider.component.html',\r\n styleUrls: ['./rm-image-slider.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.Eager,\n encapsulation: ViewEncapsulation.None\r\n})\r\nexport class RmImageSliderComponent\r\n implements OnChanges, OnInit, DoCheck, AfterViewInit, OnDestroy\r\n{\r\n // for slider\r\n sliderMainDivWidth: number = 0;\r\n imageParentDivWidth: number = 0;\r\n imageObj: Array<ImageObject> = [];\r\n ligthboxImageObj: Array<ImageObject> = [];\r\n totalImages: number = 0;\r\n leftPos: number = 0;\r\n effectStyle: string = 'all 1s ease-in-out';\r\n speed: number = 1; // default speed in second\r\n sliderPrevDisable: boolean = false;\r\n sliderNextDisable: boolean = false;\r\n slideImageCount: number = 1;\r\n sliderImageWidth: number = 205;\r\n sliderImageReceivedWidth: number | string = 205;\r\n sliderImageHeight: number = 200;\r\n sliderImageReceivedHeight: number | string = 205;\r\n sliderImageSizeWithPadding = 211;\r\n autoSlideCount: number = 0;\r\n stopSlideOnHover: boolean = true;\r\n autoSlideInterval: any;\r\n showArrowButton: boolean = true;\r\n textDirection: string = 'ltr';\r\n imageMargin: number = 3;\r\n sliderOrderType: string = 'ASC';\r\n\r\n // for swipe event\r\n private swipeCoord?: [number, number];\r\n private swipeTime?: number;\r\n\r\n // for lightbox\r\n ligthboxShow: boolean = false;\r\n activeImageIndex: number = -1;\r\n visiableImageIndex: number = 0;\r\n\r\n @ViewChild('sliderMain', { static: false }) sliderMain: any;\r\n @ViewChild('imageDiv', { static: false }) imageDiv: any;\r\n\r\n // @inputs\r\n @Input()\r\n set imageSize(data: any) {\r\n if (data && typeof data === 'object') {\r\n if (\r\n data.hasOwnProperty('space') &&\r\n typeof data['space'] === 'number' &&\r\n data['space'] > -1\r\n ) {\r\n this.imageMargin = data['space'];\r\n }\r\n if (\r\n data.hasOwnProperty('width') &&\r\n (typeof data['width'] === 'number' || typeof data['width'] === 'string')\r\n ) {\r\n this.sliderImageReceivedWidth = data['width'];\r\n // this.sliderImageSizeWithPadding = data['width'] + (this.imageMargin * 2); // addeing padding with image width\r\n }\r\n if (\r\n data.hasOwnProperty('height') &&\r\n (typeof data['height'] === 'number' ||\r\n typeof data['height'] === 'string')\r\n ) {\r\n this.sliderImageReceivedHeight = data['height'];\r\n }\r\n }\r\n }\r\n @Input() infinite: boolean = false;\r\n @Input() imagePopup: boolean = true;\r\n @Input()\r\n set direction(dir: string) {\r\n if (dir) {\r\n this.textDirection = dir;\r\n }\r\n }\r\n @Input()\r\n set animationSpeed(data: number) {\r\n if (data && typeof data === 'number' && data >= 0.1 && data <= 5) {\r\n this.speed = data;\r\n this.effectStyle = `all ${this.speed}s ease-in-out`;\r\n }\r\n }\r\n @Input() images: Array<object> = [];\r\n @Input() set slideImage(count: any) {\r\n if (count && typeof count === 'number') {\r\n this.slideImageCount = Math.round(count);\r\n }\r\n }\r\n @Input() set autoSlide(count: any) {\r\n if (\r\n count &&\r\n (typeof count === 'number' ||\r\n typeof count === 'boolean' ||\r\n typeof count === 'object')\r\n ) {\r\n if (typeof count === 'number' && count >= 1 && count <= 5) {\r\n count = Math.round(count);\r\n } else if (typeof count === 'boolean') {\r\n count = 1;\r\n } else if (\r\n typeof count === 'object' &&\r\n count.hasOwnProperty('interval') &&\r\n Math.round(count['interval']) &&\r\n Math.round(count['interval']) >= 1 &&\r\n Math.round(count['interval']) <= 5\r\n ) {\r\n this.stopSlideOnHover = count.hasOwnProperty('stopOnHover')\r\n ? count['stopOnHover']\r\n : true;\r\n count = Math.round(count['interval']);\r\n }\r\n this.autoSlideCount = count * 1000;\r\n }\r\n }\r\n @Input() set showArrow(flag: any) {\r\n if (flag !== undefined && typeof flag === 'boolean') {\r\n this.showArrowButton = flag;\r\n }\r\n }\r\n\r\n @Input() set orderType(data: string) {\r\n if (data !== undefined && typeof data === 'string') {\r\n this.sliderOrderType = data.toUpperCase();\r\n }\r\n }\r\n @Input() videoAutoPlay: boolean = false;\r\n @Input() paginationShow: boolean = false;\r\n @Input() arrowKeyMove: boolean = true;\r\n @Input() manageImageRatio: boolean = false;\r\n @Input() showVideoControls: boolean = true;\r\n @Input() set defaultActiveImage(activeIndex: number) {\r\n if (typeof activeIndex === 'number' && activeIndex > -1) {\r\n this.activeImageIndex = activeIndex;\r\n }\r\n }\r\n @Input() lazyLoading: boolean = false;\r\n\r\n // @Outputs\r\n @Output() imageClick = new EventEmitter<number>();\r\n @Output() arrowClick = new EventEmitter<object>();\r\n @Output() lightboxArrowClick = new EventEmitter<object>();\r\n @Output() lightboxClose = new EventEmitter<object>();\r\n\r\n @HostListener('window:resize', ['$event'])\r\n onResize(event: any) {\r\n this.setSliderWidth();\r\n }\r\n @HostListener('document:keyup', ['$event'])\r\n handleKeyboardEvent(event: KeyboardEvent) {\r\n if (event && event.key) {\r\n if (\r\n event.key.toLowerCase() === 'arrowright' &&\r\n !this.ligthboxShow &&\r\n this.arrowKeyMove\r\n ) {\r\n this.next();\r\n }\r\n\r\n if (\r\n event.key.toLowerCase() === 'arrowleft' &&\r\n !this.ligthboxShow &&\r\n this.arrowKeyMove\r\n ) {\r\n this.prev();\r\n }\r\n\r\n if (event.key.toLowerCase() === 'escape' && this.ligthboxShow) {\r\n this.close();\r\n }\r\n }\r\n }\r\n\r\n constructor(\r\n private cdRef: ChangeDetectorRef,\r\n @Inject(PLATFORM_ID) private platformId: Object,\r\n public imageSliderService: RmImageSliderService,\r\n private elRef: ElementRef // @Inject(ElementRef) private _elementRef: ElementRef\r\n ) {}\r\n\r\n ngOnInit() {\r\n // @TODO: for future use\r\n // console.log(this._elementRef)\r\n\r\n // for slider\r\n if (this.infinite) {\r\n this.effectStyle = 'none';\r\n this.leftPos =\r\n -1 * this.sliderImageSizeWithPadding * this.slideImageCount;\r\n for (let i = 1; i <= this.slideImageCount; i++) {\r\n this.imageObj.unshift(this.imageObj[this.imageObj.length - i]);\r\n }\r\n }\r\n }\r\n\r\n // for slider\r\n ngAfterViewInit() {\r\n this.setSliderWidth();\r\n this.cdRef.detectChanges();\r\n if (isPlatformBrowser(this.platformId)) {\r\n this.imageAutoSlide();\r\n }\r\n }\r\n\r\n ngOnDestroy() {\r\n if (this.autoSlideInterval) {\r\n clearInterval(this.autoSlideInterval);\r\n }\r\n if (this.ligthboxShow === true) {\r\n this.close();\r\n }\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges) {\r\n if (\r\n changes['images'] &&\r\n changes['images'].hasOwnProperty('previousValue') &&\r\n changes['images'].hasOwnProperty('currentValue') &&\r\n changes['images'].previousValue != changes['images'].currentValue\r\n ) {\r\n this.setSliderImages(changes['images'].currentValue);\r\n }\r\n if (changes && changes['imageSize']) {\r\n const size: SimpleChange = changes['imageSize'];\r\n if (\r\n size &&\r\n size.previousValue &&\r\n size.currentValue &&\r\n size.previousValue.width &&\r\n size.previousValue.height &&\r\n size.currentValue.width &&\r\n size.currentValue.height &&\r\n (size.previousValue.width !== size.currentValue.width ||\r\n size.previousValue.height !== size.currentValue.height)\r\n ) {\r\n this.setSliderWidth();\r\n }\r\n }\r\n }\r\n\r\n ngDoCheck() {\r\n if (\r\n this.images &&\r\n this.ligthboxImageObj &&\r\n this.images.length !== this.ligthboxImageObj.length\r\n ) {\r\n this.setSliderImages(this.images);\r\n }\r\n }\r\n\r\n setSliderImages(imgObj: any) {\r\n if (imgObj && imgObj instanceof Array && imgObj.length) {\r\n // const sliderOrderEnable = imgObj.find((img: any) => {\r\n // if (img.hasOwnProperty('order')) {\r\n // return true;\r\n // }\r\n // });\r\n const sliderOrderEnable =\r\n imgObj.find((img: any) => {\r\n return img.order !== undefined;\r\n }) !== undefined;\r\n\r\n if (sliderOrderEnable) {\r\n imgObj = this.imageSliderService.orderArray(\r\n imgObj as [],\r\n this.sliderOrderType.toUpperCase()\r\n );\r\n }\r\n\r\n this.imageObj = imgObj.map((img: any, index: any) => {\r\n img['index'] = index;\r\n return img;\r\n });\r\n this.ligthboxImageObj = [...this.imageObj];\r\n this.totalImages = this.imageObj.length;\r\n // this.imageParentDivWidth = imgObj.length * this.sliderImageSizeWithPadding;\r\n } else {\r\n this.imageObj = [];\r\n this.ligthboxImageObj = [];\r\n this.totalImages = 0;\r\n this.imageParentDivWidth = 0;\r\n this.activeImageIndex = 0;\r\n }\r\n\r\n this.setSliderWidth();\r\n }\r\n\r\n setSliderWidth() {\r\n if (\r\n this.sliderMain &&\r\n this.sliderMain.nativeElement &&\r\n this.sliderMain.nativeElement.offsetWidth\r\n ) {\r\n this.sliderMainDivWidth = this.sliderMain.nativeElement.offsetWidth;\r\n }\r\n\r\n if (this.sliderMainDivWidth && this.sliderImageReceivedWidth) {\r\n if (typeof this.sliderImageReceivedWidth === 'number') {\r\n this.sliderImageWidth = this.sliderImageReceivedWidth;\r\n } else if (typeof this.sliderImageReceivedWidth === 'string') {\r\n if (this.sliderImageReceivedWidth.indexOf('px') >= 0) {\r\n this.sliderImageWidth = parseFloat(this.sliderImageReceivedWidth);\r\n } else if (this.sliderImageReceivedWidth.indexOf('%') >= 0) {\r\n this.sliderImageWidth = +(\r\n (this.sliderMainDivWidth *\r\n parseFloat(this.sliderImageReceivedWidth)) /\r\n 100\r\n ).toFixed(2);\r\n } else if (parseFloat(this.sliderImageReceivedWidth)) {\r\n this.sliderImageWidth = parseFloat(this.sliderImageReceivedWidth);\r\n }\r\n }\r\n }\r\n if (isPlatformBrowser(this.platformId)) {\r\n if (window && window.innerHeight && this.sliderImageReceivedHeight) {\r\n if (typeof this.sliderImageReceivedHeight === 'number') {\r\n this.sliderImageHeight = this.sliderImageReceivedHeight;\r\n } else if (typeof this.sliderImageReceivedHeight === 'string') {\r\n if (this.sliderImageReceivedHeight.indexOf('px') >= 0) {\r\n this.sliderImageHeight = parseFloat(this.sliderImageReceivedHeight);\r\n } else if (this.sliderImageReceivedHeight.indexOf('%') >= 0) {\r\n this.sliderImageHeight = +(\r\n (window.innerHeight *\r\n parseFloat(this.sliderImageReceivedHeight)) /\r\n 100\r\n ).toFixed(2);\r\n } else if (parseFloat(this.sliderImageReceivedHeight)) {\r\n this.sliderImageHeight = parseFloat(this.sliderImageReceivedHeight);\r\n }\r\n }\r\n }\r\n }\r\n this.sliderImageSizeWithPadding =\r\n this.sliderImageWidth + this.imageMargin * 2;\r\n this.imageParentDivWidth =\r\n this.imageObj.length * this.sliderImageSizeWithPadding;\r\n if (\r\n this.imageDiv &&\r\n this.imageDiv.nativeElement &&\r\n this.imageDiv.nativeElement.offsetWidth\r\n ) {\r\n const staticLeftPos =\r\n 0 -\r\n (this.sliderImageSizeWithPadding * this.visiableImageIndex +\r\n this.imageMargin * 2);\r\n this.leftPos = this.infinite\r\n ? -1 * this.sliderImageSizeWithPadding * this.slideImageCount\r\n : staticLeftPos;\r\n }\r\n this.nextPrevSliderButtonDisable();\r\n }\r\n\r\n imageOnClick(index: number) {\r\n this.activeImageIndex = index;\r\n if (this.imagePopup) {\r\n this.showLightbox();\r\n }\r\n this.imageClick.emit(index);\r\n }\r\n\r\n imageAutoSlide() {\r\n if (this.infinite && this.autoSlideCount && !this.ligthboxShow) {\r\n this.autoSlideInterval = setInterval(() => {\r\n this.next();\r\n }, this.autoSlideCount);\r\n }\r\n }\r\n\r\n imageMouseEnterHandler() {\r\n if (this.infinite && this.autoSlideCount && this.autoSlideInterval) {\r\n clearInterval(this.autoSlideInterval);\r\n }\r\n }\r\n\r\n prev() {\r\n if (!this.sliderPrevDisable) {\r\n if (this.infinite) {\r\n this.infinitePrevImg();\r\n } else {\r\n this.prevImg();\r\n }\r\n\r\n //this.arrowClick.emit(PREV_ARROW_CLICK_MESSAGE);\r\n this.sliderArrowDisableTeam(PREV_ARROW_CLICK_MESSAGE);\r\n this.getVisiableIndex();\r\n }\r\n }\r\n\r\n next() {\r\n if (!this.sliderNextDisable) {\r\n if (this.infinite) {\r\n this.infiniteNextImg();\r\n } else {\r\n this.nextImg();\r\n }\r\n\r\n //this.arrowClick.emit(NEXT_ARROW_CLICK_MESSAGE);\r\n this.sliderArrowDisableTeam(NEXT_ARROW_CLICK_MESSAGE);\r\n this.getVisiableIndex();\r\n }\r\n }\r\n\r\n prevImg() {\r\n if (\r\n 0 >=\r\n this.leftPos + this.sliderImageSizeWithPadding * this.slideImageCount\r\n ) {\r\n this.leftPos += this.sliderImageSizeWithPadding * this.slideImageCount;\r\n } else {\r\n this.leftPos = 0;\r\n }\r\n }\r\n\r\n nextImg() {\r\n if (\r\n this.imageParentDivWidth + this.leftPos - this.sliderMainDivWidth >\r\n this.sliderImageSizeWithPadding * this.slideImageCount\r\n ) {\r\n this.leftPos -= this.sliderImageSizeWithPadding * this.slideImageCount;\r\n } else if (\r\n this.imageParentDivWidth + this.leftPos - this.sliderMainDivWidth >\r\n 0\r\n ) {\r\n this.leftPos -=\r\n this.imageParentDivWidth + this.leftPos - this.sliderMainDivWidth;\r\n }\r\n }\r\n\r\n infinitePrevImg() {\r\n this.effectStyle = `all ${this.speed}s ease-in-out`;\r\n this.leftPos = 0;\r\n\r\n setTimeout(() => {\r\n this.effectStyle = 'none';\r\n this.leftPos =\r\n -1 * this.sliderImageSizeWithPadding * this.slideImageCount;\r\n for (let i = 0; i < this.slideImageCount; i++) {\r\n this.imageObj.unshift(\r\n this.imageObj[this.imageObj.length - this.slideImageCount - 1]\r\n );\r\n this.imageObj.pop();\r\n }\r\n }, this.speed * 1000);\r\n }\r\n\r\n infiniteNextImg() {\r\n this.effectStyle = `all ${this.speed}s ease-in-out`;\r\n this.leftPos = -2 * this.sliderImageSizeWithPadding * this.slideImageCount;\r\n setTimeout(() => {\r\n this.effectStyle = 'none';\r\n for (let i = 0; i < this.slideImageCount; i++) {\r\n this.imageObj.push(this.imageObj[this.slideImageCount]);\r\n this.imageObj.shift();\r\n }\r\n this.leftPos =\r\n -1 * this.sliderImageSizeWithPadding * this.slideImageCount;\r\n }, this.speed * 1000);\r\n }\r\n\r\n getVisiableIndex() {\r\n const currentIndex = Math.round(\r\n (Math.abs(this.leftPos) + this.sliderImageWidth) / this.sliderImageWidth\r\n );\r\n if (\r\n this.imageObj &&\r\n this.imageObj[currentIndex - 1] &&\r\n this.imageObj[currentIndex - 1]['index']\r\n ) {\r\n this.visiableImageIndex = this.imageObj[currentIndex - 1]['index'] ?? 0;\r\n }\r\n }\r\n\r\n /**\r\n * Disable slider left/right arrow when image moving\r\n */\r\n sliderArrowDisableTeam(msg: string) {\r\n this.sliderNextDisable = true;\r\n this.sliderPrevDisable = true;\r\n setTimeout(() => {\r\n this.nextPrevSliderButtonDisable(msg);\r\n }, this.speed * 1000);\r\n }\r\n\r\n nextPrevSliderButtonDisable(msg?: string) {\r\n this.sliderNextDisable = false;\r\n this.sliderPrevDisable = false;\r\n const actionMsg = {} as any;\r\n if (!this.infinite) {\r\n if (this.imageParentDivWidth + this.leftPos <= this.sliderMainDivWidth) {\r\n this.sliderNextDisable = true;\r\n }\r\n\r\n if (this.leftPos >= 0) {\r\n this.sliderPrevDisable = true;\r\n }\r\n\r\n actionMsg['prevDisable'] = this.sliderPrevDisable;\r\n actionMsg['nextDisable'] = this.sliderNextDisable;\r\n }\r\n\r\n if (msg) {\r\n this.arrowClick.emit({\r\n action: msg,\r\n ...actionMsg,\r\n });\r\n }\r\n }\r\n\r\n // for lightbox\r\n showLightbox() {\r\n if (this.imageObj.length) {\r\n this.imageMouseEnterHandler();\r\n this.ligthboxShow = true;\r\n this.elRef.nativeElement.ownerDocument.body.style.overflow = 'hidden';\r\n }\r\n }\r\n\r\n close() {\r\n this.ligthboxShow = false;\r\n this.elRef.nativeElement.ownerDocument.body.style.overflow = '';\r\n this.lightboxClose.emit();\r\n this.imageAutoSlide();\r\n }\r\n\r\n lightboxArrowClickHandler(event: any) {\r\n this.lightboxArrowClick.emit(event);\r\n }\r\n\r\n swipe(e: TouchEvent, when: string): void {\r\n const coord: [number, number] = [\r\n e.changedTouches[0].pageX,\r\n e.changedTouches[0].pageY,\r\n ];\r\n const time = new Date().getTime();\r\n\r\n if (when === 'start') {\r\n this.swipeCoord = coord;\r\n this.swipeTime = time;\r\n } else if (when === 'end' && this.swipeCoord && this.swipeTime) {\r\n const direction = [\r\n coord[0] - this.swipeCoord[0],\r\n coord[1] - this.swipeCoord[1],\r\n ];\r\n const duration = time - this.swipeTime;\r\n\r\n if (\r\n duration < 1000 && //\r\n Math.abs(direction[0]) > 30 && // Long enough\r\n Math.abs(direction[0]) > Math.abs(direction[1] * 3)\r\n ) {\r\n // Horizontal enough\r\n if (direction[0] < 0) {\r\n this.next();\r\n } else {\r\n this.prev();\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","<div class=\"ng-image-slider\" [ngStyle]=\"{'height':sliderImageHeight+'px'}\">\r\n <div class=\"ng-image-slider-container\">\r\n <div class=\"main\" [ngStyle]=\"{'height':sliderImageHeight+'px'}\" #sliderMain>\r\n @if (imageObj.length) {\r\n <div class=\"main-inner\" [ngClass]=\"{'with-ng-main-pagination': paginationShow}\"\r\n [ngStyle]=\"{'margin-left':leftPos+'px', 'width':imageParentDivWidth+'px', 'transition': effectStyle}\"\r\n (touchstart)=\"swipe($event, 'start')\" (touchend)=\"swipe($event, 'end')\">\r\n @for (img of imageObj; track img; let i = $index) {\r\n <div\r\n [ngClass]=\"{'image-popup': imagePopup, 'selected-image': activeImageIndex == i}\"\r\n [ngStyle]=\"{'width':sliderImageWidth+'px', 'margin-left':imageMargin+'px', 'margin-right':imageMargin+'px'}\"\r\n class=\"img-div\" (click)=\"imageOnClick(img.index)\" (mouseenter)=\"stopSlideOnHover && imageMouseEnterHandler()\"\r\n (mouseleave)=\"stopSlideOnHover && imageAutoSlide()\" #imageDiv>\r\n <custom-img [imageUrl]=\"img?.thumbImage || img?.posterImage || img?.video\"\r\n [isVideo]=\"!!(img?.posterImage || img?.video)\" [alt]=\"img?.alt || img?.title || ''\"\r\n [title]=\"img?.title || img?.alt || ''\" [direction]=\"textDirection\" [ratio]=\"manageImageRatio\"\r\n [lazy]=\"lazyLoading\">\r\n </custom-img>\r\n @if (img?.title) {\r\n <div [dir]=\"textDirection\" class=\"caption\">{{ img?.title }}</div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n @if (!imageObj.length) {\r\n <div class=\"ng-image-slider-error\">\r\n <span class=\"ng-image-slider-loader\"></span>\r\n </div>\r\n }\r\n @if (showArrowButton && imageObj.length > 1) {\r\n <a [ngClass]=\"{'disable': sliderPrevDisable}\"\r\n class=\"prev icons prev-icon\" (click)=\"prev()\" (mouseenter)=\"stopSlideOnHover && imageMouseEnterHandler()\"\r\n (mouseleave)=\"stopSlideOnHover && imageAutoSlide()\">‹</a>\r\n }\r\n @if (showArrowButton && imageObj.length > 1) {\r\n <a [ngClass]=\"{'disable': sliderNextDisable}\"\r\n class=\"next icons next-icon\" (click)=\"next()\" (mouseenter)=\"imageMouseEnterHandler()\"\r\n (mouseleave)=\"imageAutoSlide()\">›</a>\r\n }\r\n </div>\r\n @if (imageObj.length && paginationShow) {\r\n <div class=\"ng-main-pagination\">{{visiableImageIndex + 1}} of\r\n {{totalImages}}</div>\r\n }\r\n </div>\r\n</div>\r\n@if (ligthboxShow) {\r\n <div>\r\n <slider-lightbox [paginationShow]=\"paginationShow\" [showVideoControls]=\"showVideoControls\"\r\n [arrowKeyMove]=\"arrowKeyMove\" [images]=\"ligthboxImageObj\" [infinite]=\"infinite\" [animationSpeed]=\"speed\"\r\n [imageIndex]=\"activeImageIndex\" [show]=\"ligthboxShow\" [direction]=\"textDirection\" [videoAutoPlay]=\"videoAutoPlay\"\r\n (prevImage)=\"lightboxArrowClickHandler($event)\" (nextImage)=\"lightboxArrowClickHandler($event)\" (close)=\"close()\">\r\n </slider-lightbox>\r\n </div>\r\n}","/*\r\n * Public API Surface of rm-image-slider\r\n */\r\n\r\nexport * from './lib/rm-image-slider.service';\r\nexport * from './lib/rm-image-slider.component';\r\nexport * from './lib/interface';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i3","i1.RmImageSliderService","i2"],"mappings":"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