├── .gitignore ├── README.md ├── dist └── ngx-image-gallery │ ├── README.md │ ├── bundles │ ├── ngx-image-gallery.umd.js │ ├── ngx-image-gallery.umd.js.map │ ├── ngx-image-gallery.umd.min.js │ └── ngx-image-gallery.umd.min.js.map │ ├── esm2015 │ ├── lib │ │ ├── components │ │ │ └── ngx-image-gallery │ │ │ │ └── ngx-image-gallery.component.js │ │ ├── directives │ │ │ ├── click-outside.directive.js │ │ │ └── mousewheel.directive.js │ │ ├── index.js │ │ └── ngx-image-gallery.conf.js │ ├── ngx-image-gallery.js │ └── public-api.js │ ├── esm5 │ ├── lib │ │ ├── components │ │ │ └── ngx-image-gallery │ │ │ │ └── ngx-image-gallery.component.js │ │ ├── directives │ │ │ ├── click-outside.directive.js │ │ │ └── mousewheel.directive.js │ │ ├── index.js │ │ └── ngx-image-gallery.conf.js │ ├── ngx-image-gallery.js │ └── public-api.js │ ├── fesm2015 │ ├── ngx-image-gallery.js │ └── ngx-image-gallery.js.map │ ├── fesm5 │ ├── ngx-image-gallery.js │ └── ngx-image-gallery.js.map │ ├── lib │ ├── components │ │ └── ngx-image-gallery │ │ │ └── ngx-image-gallery.component.d.ts │ ├── directives │ │ ├── click-outside.directive.d.ts │ │ └── mousewheel.directive.d.ts │ ├── index.d.ts │ └── ngx-image-gallery.conf.d.ts │ ├── ngx-image-gallery.d.ts │ ├── ngx-image-gallery.metadata.json │ ├── package.json │ └── public-api.d.ts ├── docs ├── 3rdpartylicenses.txt ├── favicon.ico ├── index.html ├── main-es2015.68a712c660a282149625.js ├── main-es5.68a712c660a282149625.js ├── polyfills-es2015.1f913f16a2d346cc8bdc.js ├── polyfills-es5.1a3c78b07cd6f16c6e9a.js ├── runtime-es2015.0811dcefd377500b5b1a.js ├── runtime-es5.0811dcefd377500b5b1a.js └── styles.09e2c710755c8867a460.css ├── preview ├── .editorconfig ├── .gitignore ├── README.md ├── angular.json ├── browserslist ├── e2e │ ├── protractor.conf.js │ ├── src │ │ ├── app.e2e-spec.ts │ │ └── app.po.ts │ └── tsconfig.json ├── karma.conf.js ├── package-lock.json ├── package.json ├── src │ ├── app │ │ ├── app.component.html │ │ ├── app.component.scss │ │ ├── app.component.ts │ │ └── app.module.ts │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.scss │ ├── test.ts │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ └── typings.d.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.spec.json └── tslint.json └── src ├── .editorconfig ├── .gitignore ├── angular.json ├── package-lock.json ├── package.json ├── projects └── ngx-image-gallery │ ├── README.md │ ├── karma.conf.js │ ├── ng-package.json │ ├── package.json │ ├── src │ ├── lib │ │ ├── components │ │ │ └── ngx-image-gallery │ │ │ │ ├── ngx-image-gallery.component.html │ │ │ │ ├── ngx-image-gallery.component.js │ │ │ │ ├── ngx-image-gallery.component.scss │ │ │ │ └── ngx-image-gallery.component.ts │ │ ├── directives │ │ │ ├── click-outside.directive.js │ │ │ ├── click-outside.directive.ts │ │ │ ├── mousewheel.directive.js │ │ │ └── mousewheel.directive.ts │ │ ├── index.ts │ │ └── ngx-image-gallery.conf.ts │ ├── public-api.ts │ └── test.ts │ ├── tsconfig.lib.json │ ├── tsconfig.lib.prod.json │ ├── tsconfig.spec.json │ └── tslint.json ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This project is no longer maintained. Please consider other image galleries. 2 | --- 3 | 4 | # ngx-image-gallery 5 | Probably the best Angular 4+ modal and inline image gallery. Angular upgrade for ng-image-gallery. 6 | 7 | ![preview](https://i.imgur.com/1gGxBLd.jpg) 8 | 9 | [![npm](https://img.shields.io/npm/dt/ngx-image-gallery.svg?style=flat-square)](https://www.npmjs.com/package/ngx-image-gallery) 10 | [![npm](https://img.shields.io/npm/v/ngx-image-gallery.svg?style=flat-square)](https://www.npmjs.com/package/ngx-image-gallery) 11 | [![David](https://img.shields.io/david/thatisuday/ngx-image-gallery.svg?style=flat-square)](https://www.npmjs.com/package/ngx-image-gallery) 12 | [![preview](https://img.shields.io/badge/preview-click_here-green.svg?style=flat-square)](https://thatisuday.github.io/ngx-image-gallery) 13 | 14 | ## Prerequisites 15 | 16 | - Hammerjs (required for swipe) 17 | ``` 18 | npm i -S hammerjs lodash 19 | ``` 20 | 21 | Then import hammerjs into your project (tip: in you main.ts file), e.g: 22 | ``` 23 | import 'hammerjs'; 24 | import { enableProdMode } from '@angular/core'; 25 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 26 | 27 | import { AppModule } from './app/app.module'; 28 | import { environment } from './environments/environment'; 29 | 30 | if (environment.production) { 31 | enableProdMode(); 32 | } 33 | 34 | document.addEventListener('DOMContentLoaded', () => { 35 | platformBrowserDynamic().bootstrapModule(AppModule) 36 | .catch(err => console.log(err)); 37 | }); 38 | 39 | ``` 40 | 41 | 42 | ## Install 43 | ```bash 44 | npm install --save @web-aid-kit/ngx-image-gallery 45 | ``` 46 | 47 | ## Import 48 | ```typescript 49 | import { NgxImageGalleryModule } from '@web-aid-kit/ngx-image-gallery'; 50 | 51 | @NgModule({ 52 | ..., 53 | imports: [ 54 | NgxImageGalleryModule, 55 | ... 56 | ] 57 | }) 58 | export class AppModule { } 59 | ``` 60 | 61 | ## Use 62 | 63 | ```html 64 | // app.component.html 65 | 66 | 75 | ``` 76 | 77 | ## Configure 78 | ```ts 79 | import { Component, OnInit, ViewChild } from '@angular/core'; 80 | import { NgxImageGalleryComponent, GALLERY_IMAGE, GALLERY_CONF } from '@web-aid-kit/ngx-image-gallery'; 81 | 82 | @Component({ 83 | selector: 'app-root', 84 | templateUrl: './app.component.html', 85 | styleUrls: ['./app.component.scss'] 86 | }) 87 | export class AppComponent implements OnInit { 88 | // get reference to gallery component 89 | @ViewChild(NgxImageGalleryComponent) ngxImageGallery: NgxImageGalleryComponent; 90 | 91 | // gallery configuration 92 | conf: GALLERY_CONF = { 93 | imageOffset: '0px', 94 | showDeleteControl: false, 95 | showImageTitle: false, 96 | }; 97 | 98 | // gallery images 99 | images: GALLERY_IMAGE[] = [ 100 | { 101 | url: "https://images.pexels.com/photos/669013/pexels-photo-669013.jpeg?w=1260", 102 | altText: 'woman-in-black-blazer-holding-blue-cup', 103 | title: 'woman-in-black-blazer-holding-blue-cup', 104 | thumbnailUrl: "https://images.pexels.com/photos/669013/pexels-photo-669013.jpeg?w=60" 105 | }, 106 | { 107 | url: "https://images.pexels.com/photos/669006/pexels-photo-669006.jpeg?w=1260", 108 | altText: 'two-woman-standing-on-the-ground-and-staring-at-the-mountain', 109 | extUrl: 'https://www.pexels.com/photo/two-woman-standing-on-the-ground-and-staring-at-the-mountain-669006/', 110 | thumbnailUrl: "https://images.pexels.com/photos/669006/pexels-photo-669006.jpeg?w=60" 111 | }, 112 | ]; 113 | 114 | constructor(){} 115 | 116 | ngOnInit() {} 117 | 118 | // METHODS 119 | // open gallery 120 | openGallery(index: number = 0) { 121 | this.ngxImageGallery.open(index); 122 | } 123 | 124 | // close gallery 125 | closeGallery() { 126 | this.ngxImageGallery.close(); 127 | } 128 | 129 | // set new active(visible) image in gallery 130 | newImage(index: number = 0) { 131 | this.ngxImageGallery.setActiveImage(index); 132 | } 133 | 134 | // next image in gallery 135 | nextImage(index: number = 0) { 136 | this.ngxImageGallery.next(); 137 | } 138 | 139 | // prev image in gallery 140 | prevImage(index: number = 0) { 141 | this.ngxImageGallery.prev(); 142 | } 143 | 144 | /**************************************************/ 145 | 146 | // EVENTS 147 | // callback on gallery opened 148 | galleryOpened(index) { 149 | console.info('Gallery opened at index ', index); 150 | } 151 | 152 | // callback on gallery closed 153 | galleryClosed() { 154 | console.info('Gallery closed.'); 155 | } 156 | 157 | // callback on gallery image clicked 158 | galleryImageClicked(index) { 159 | console.info('Gallery image clicked with index ', index); 160 | } 161 | 162 | // callback on gallery image changed 163 | galleryImageChanged(index) { 164 | console.info('Gallery image changed to index ', index); 165 | } 166 | 167 | // callback on user clicked delete button 168 | deleteImage(index) { 169 | console.info('Delete image at index ', index); 170 | } 171 | } 172 | ``` 173 | 174 | ### Interfaces 175 | ```ts 176 | // gallery configuration 177 | export interface GALLERY_CONF { 178 | imageBorderRadius?: string; // css border radius of image (default 3px) 179 | imageOffset?: string; // add gap between image and it's container (default 20px) 180 | imagePointer? :boolean; // show a pointer on image, should be true when handling onImageClick event (default false) 181 | showDeleteControl?: boolean; // show image delete icon (default false) 182 | showCloseControl?: boolean; // show gallery close icon (default true) 183 | showExtUrlControl?: boolean; // show image external url icon (default true) 184 | showImageTitle?: boolean; // show image title text (default true) 185 | showThumbnails?: boolean; // show thumbnails (default true) 186 | closeOnEsc?: boolean; // close gallery on `Esc` button press (default true) 187 | reactToKeyboard?: boolean; // change image on keyboard arrow press (default true) 188 | reactToMouseWheel?: boolean; // change image on mouse wheel scroll (default true) 189 | reactToRightClick?: boolean; // disable right click on gallery (default false) 190 | thumbnailSize?: number; // thumbnail size (default 30) 191 | backdropColor?: string; // gallery backdrop (background) color (default rgba(13,13,14,0.85)) 192 | inline?: boolean; // make gallery inline (default false) 193 | showArrows?: boolean; // show prev / next arrows (default true) 194 | } 195 | 196 | // gallery image 197 | export interface GALLERY_IMAGE { 198 | url: string; // url of the image 199 | thumbnailUrl?: string; // thumbnail url (recommended), if not present, gallery will use `url` property to get thumbnail image. 200 | altText?: string; // alt text for image 201 | title?: string; // title of the image 202 | extUrl?: string; // external url of image 203 | extUrlTarget?: string; // external url target e.g. '_blank', '_self' etc. 204 | } 205 | ``` 206 | 207 | > All properties ending with `?` are optional. 208 | 209 | # Make gallery inline 210 | You can make gallery **inline** like a carousel by setting `conf.inline` to `true` but make sure to change `conf.backdropColor` as well if you need white backdrop color. Also `width` and `height` of the gallery can be adjusted by manually applying css styles with `!important` flag on gallery element. 211 | 212 | # Dynamic Update 213 | You can update gallery images `images` and gallery configuration `conf` anytime you want even when gallery is opened but due to Angular's change detection restrictions you must assign these variable to new value instead of changing internal properties as mentioned below. 214 | 215 | ```ts 216 | // change images 217 | this.images = this.images.concat([...]); 218 | 219 | // change conf 220 | this.conf = {...}; 221 | ``` 222 | -------------------------------------------------------------------------------- /dist/ngx-image-gallery/README.md: -------------------------------------------------------------------------------- 1 | # Need maintainers 2 | Due to my hectic schedule, it is getting hard to maintain this repository. If anybody is interested to work on this project, please give a pull request to fix some critical issues and enhancements. 3 | 4 | --- 5 | 6 | # ngx-image-gallery 7 | Probably the best Angular 4+ modal and inline image gallery. Angular upgrade for ng-image-gallery. 8 | 9 | [![preview](https://i.imgur.com/1gGxBLd.jpg)](https://thatisuday.github.io) 10 | 11 | [![npm](https://img.shields.io/npm/dt/ngx-image-gallery.svg?style=flat-square)](https://www.npmjs.com/package/ngx-image-gallery) 12 | [![npm](https://img.shields.io/npm/v/ngx-image-gallery.svg?style=flat-square)](https://www.npmjs.com/package/ngx-image-gallery) 13 | [![David](https://img.shields.io/david/thatisuday/ngx-image-gallery.svg?style=flat-square)](https://www.npmjs.com/package/ngx-image-gallery) 14 | [![preview](https://img.shields.io/badge/preview-click_here-green.svg?style=flat-square)](https://thatisuday.github.io/ngx-image-gallery) 15 | 16 | ## Prerequisites 17 | 18 | - Hammerjs (required for swipe) 19 | ``` 20 | npm i -S hammerjs lodash 21 | ``` 22 | 23 | Then import hammerjs into your project (tip: in you main.ts file), e.g: 24 | ``` 25 | import 'hammerjs'; 26 | import { enableProdMode } from '@angular/core'; 27 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 28 | 29 | import { AppModule } from './app/app.module'; 30 | import { environment } from './environments/environment'; 31 | 32 | if (environment.production) { 33 | enableProdMode(); 34 | } 35 | 36 | document.addEventListener('DOMContentLoaded', () => { 37 | platformBrowserDynamic().bootstrapModule(AppModule) 38 | .catch(err => console.log(err)); 39 | }); 40 | 41 | ``` 42 | 43 | 44 | ## Install 45 | ```bash 46 | npm install --save @web-aid-kit/ngx-image-gallery 47 | ``` 48 | 49 | ## Import 50 | ```typescript 51 | import { NgxImageGalleryModule } from '@web-aid-kit/ngx-image-gallery'; 52 | 53 | @NgModule({ 54 | ..., 55 | imports: [ 56 | NgxImageGalleryModule, 57 | ... 58 | ] 59 | }) 60 | export class AppModule { } 61 | ``` 62 | 63 | ## Use 64 | 65 | ```html 66 | // app.component.html 67 | 68 | 77 | ``` 78 | 79 | ## Configure 80 | ```ts 81 | import { Component, OnInit, ViewChild } from '@angular/core'; 82 | import { NgxImageGalleryComponent, GALLERY_IMAGE, GALLERY_CONF } from '@web-aid-kit/ngx-image-gallery'; 83 | 84 | @Component({ 85 | selector: 'app-root', 86 | templateUrl: './app.component.html', 87 | styleUrls: ['./app.component.scss'] 88 | }) 89 | export class AppComponent implements OnInit { 90 | // get reference to gallery component 91 | @ViewChild(NgxImageGalleryComponent) ngxImageGallery: NgxImageGalleryComponent; 92 | 93 | // gallery configuration 94 | conf: GALLERY_CONF = { 95 | imageOffset: '0px', 96 | showDeleteControl: false, 97 | showImageTitle: false, 98 | }; 99 | 100 | // gallery images 101 | images: GALLERY_IMAGE[] = [ 102 | { 103 | url: "https://images.pexels.com/photos/669013/pexels-photo-669013.jpeg?w=1260", 104 | altText: 'woman-in-black-blazer-holding-blue-cup', 105 | title: 'woman-in-black-blazer-holding-blue-cup', 106 | thumbnailUrl: "https://images.pexels.com/photos/669013/pexels-photo-669013.jpeg?w=60" 107 | }, 108 | { 109 | url: "https://images.pexels.com/photos/669006/pexels-photo-669006.jpeg?w=1260", 110 | altText: 'two-woman-standing-on-the-ground-and-staring-at-the-mountain', 111 | extUrl: 'https://www.pexels.com/photo/two-woman-standing-on-the-ground-and-staring-at-the-mountain-669006/', 112 | thumbnailUrl: "https://images.pexels.com/photos/669006/pexels-photo-669006.jpeg?w=60" 113 | }, 114 | ]; 115 | 116 | constructor(){} 117 | 118 | ngOnInit() {} 119 | 120 | // METHODS 121 | // open gallery 122 | openGallery(index: number = 0) { 123 | this.ngxImageGallery.open(index); 124 | } 125 | 126 | // close gallery 127 | closeGallery() { 128 | this.ngxImageGallery.close(); 129 | } 130 | 131 | // set new active(visible) image in gallery 132 | newImage(index: number = 0) { 133 | this.ngxImageGallery.setActiveImage(index); 134 | } 135 | 136 | // next image in gallery 137 | nextImage(index: number = 0) { 138 | this.ngxImageGallery.next(); 139 | } 140 | 141 | // prev image in gallery 142 | prevImage(index: number = 0) { 143 | this.ngxImageGallery.prev(); 144 | } 145 | 146 | /**************************************************/ 147 | 148 | // EVENTS 149 | // callback on gallery opened 150 | galleryOpened(index) { 151 | console.info('Gallery opened at index ', index); 152 | } 153 | 154 | // callback on gallery closed 155 | galleryClosed() { 156 | console.info('Gallery closed.'); 157 | } 158 | 159 | // callback on gallery image clicked 160 | galleryImageClicked(index) { 161 | console.info('Gallery image clicked with index ', index); 162 | } 163 | 164 | // callback on gallery image changed 165 | galleryImageChanged(index) { 166 | console.info('Gallery image changed to index ', index); 167 | } 168 | 169 | // callback on user clicked delete button 170 | deleteImage(index) { 171 | console.info('Delete image at index ', index); 172 | } 173 | } 174 | ``` 175 | 176 | ### Interfaces 177 | ```ts 178 | // gallery configuration 179 | export interface GALLERY_CONF { 180 | imageBorderRadius?: string; // css border radius of image (default 3px) 181 | imageOffset?: string; // add gap between image and it's container (default 20px) 182 | imagePointer? :boolean; // show a pointer on image, should be true when handling onImageClick event (default false) 183 | showDeleteControl?: boolean; // show image delete icon (default false) 184 | showCloseControl?: boolean; // show gallery close icon (default true) 185 | showExtUrlControl?: boolean; // show image external url icon (default true) 186 | showImageTitle?: boolean; // show image title text (default true) 187 | showThumbnails?: boolean; // show thumbnails (default true) 188 | closeOnEsc?: boolean; // close gallery on `Esc` button press (default true) 189 | reactToKeyboard?: boolean; // change image on keyboard arrow press (default true) 190 | reactToMouseWheel?: boolean; // change image on mouse wheel scroll (default true) 191 | reactToRightClick?: boolean; // disable right click on gallery (default false) 192 | thumbnailSize?: number; // thumbnail size (default 30) 193 | backdropColor?: string; // gallery backdrop (background) color (default rgba(13,13,14,0.85)) 194 | inline?: boolean; // make gallery inline (default false) 195 | showArrows?: boolean; // show prev / next arrows (default true) 196 | } 197 | 198 | // gallery image 199 | export interface GALLERY_IMAGE { 200 | url: string; // url of the image 201 | thumbnailUrl?: string; // thumbnail url (recommended), if not present, gallery will use `url` property to get thumbnail image. 202 | altText?: string; // alt text for image 203 | title?: string; // title of the image 204 | extUrl?: string; // external url of image 205 | extUrlTarget?: string; // external url target e.g. '_blank', '_self' etc. 206 | } 207 | ``` 208 | 209 | > All properties ending with `?` are optional. 210 | 211 | # Make gallery inline 212 | You can make gallery **inline** like a carousel by setting `conf.inline` to `true` but make sure to change `conf.backdropColor` as well if you need white backdrop color. Also `width` and `height` of the gallery can be adjusted by manually applying css styles with `!important` flag on gallery element. 213 | 214 | # Dynamic Update 215 | You can update gallery images `images` and gallery configuration `conf` anytime you want even when gallery is opened but due to Angular's change detection restrictions you must assign these variable to new value instead of changing internal properties as mentioned below. 216 | 217 | ```ts 218 | // change images 219 | this.images = this.images.concat([...]); 220 | 221 | // change conf 222 | this.conf = {...}; 223 | ``` -------------------------------------------------------------------------------- /dist/ngx-image-gallery/bundles/ngx-image-gallery.umd.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["ng://ngx-image-gallery/lib/components/ngx-image-gallery/ngx-image-gallery.component.ts","ng://ngx-image-gallery/lib/directives/click-outside.directive.ts","ng://ngx-image-gallery/lib/directives/mousewheel.directive.ts","ng://ngx-image-gallery/lib/index.ts"],"names":["KEY_CODES","37","39","27","DEFAULT_CONF","imageBorderRadius","imageOffset","imagePointer","showDeleteControl","showCloseControl","showExtUrlControl","showImageTitle","showThumbnails","closeOnEsc","reactToKeyboard","reactToMouseWheel","reactToRightClick","thumbnailSize","backdropColor","inline","showArrows","NgxImageGalleryComponent","sanitizer","galleryElem","renderer","cdRef","_this","this","opened","conf","images","onOpen","EventEmitter","onClose","onDelete","onImageChange","onImageClicked","onError","loading","activeImageIndex","thumbnailMargin","thumbnailsScrollerLeftMargin","fitThumbnails","debounce","thumbnailParams","thumbnailsRenderParams","newThumbnailMargin","debouncedPrev","prev","leading","trailing","debouncedNext","next","Object","defineProperty","prototype","length","thumbnailsContainerWidth","thumbnailsElem","nativeElement","offsetWidth","thumbnailsInView","Math","floor","newThumbnailSize","outThumbnails","setGalleryConf","assign","loadImage","index","galleryImage","_cached","Promise","resolve","reject","image","Image","src","url","onload","onerror","error","activateImage","imageIndex","emit","then","_imageIndex","detectChanges","setTimeout","scrollThumbnails","catch","console","warn","ngOnInit","setStyle","addClass","open","ngOnChanges","changes","firstChange","currentValue","previousValue","onKeyboardInput","event","keyCode","close","onWindowResize","onFirstImage","onLastImage","setActiveImage","deleteImage","mouseWheelUp","mouseWheelDown","clickOnImage","rightClickOnImage","stopPropagation","DomSanitizer","ElementRef","Renderer2","ChangeDetectorRef","__decorate","HostBinding","Input","Output","ViewChild","HostListener","tslib","Component","selector","template","ClickOutsideDirective","_elementRef","clickOutside","onClick","$event","targetElement","contains","Directive","MouseWheelDirective","onMouseWheelChrome","mouseWheelFunc","onMouseWheelFirefox","onMouseWheelIE","window","delta","max","min","wheelDelta","detail","returnValue","preventDefault","NgxImageGalleryModule","NgModule","imports","CommonModule","declarations","exports"],"mappings":"ufAsBA,IAAMA,EAAY,CACdC,GAAI,OACJC,GAAI,QACJC,GAAI,OAIFC,EAA6B,CAC/BC,kBAAmB,MACnBC,YAAa,OACbC,cAAc,EACdC,mBAAmB,EACnBC,kBAAkB,EAClBC,mBAAmB,EACnBC,gBAAgB,EAChBC,gBAAgB,EAChBC,YAAY,EACZC,iBAAiB,EACjBC,mBAAmB,EACnBC,mBAAmB,EACnBC,cAAe,GACfC,cAAe,sBACfC,QAAQ,EACRC,YAAY,gBAoLZ,SAAAC,EACWC,EACCC,EACAC,EACAC,GAJZ,IAAAC,EAAAC,KACWA,KAAAL,UAAAA,EACCK,KAAAJ,YAAAA,EACAI,KAAAH,SAAAA,EACAG,KAAAF,MAAAA,EA7KiBE,KAAAC,QAAkB,EAGtCD,KAAAE,KAAqB,GAGrBF,KAAAG,OAA0B,GAGzBH,KAAAI,OAAS,IAAIC,EAAAA,aACbL,KAAAM,QAAU,IAAID,EAAAA,aACdL,KAAAO,SAAW,IAAIF,EAAAA,aACfL,KAAAQ,cAAgB,IAAIH,EAAAA,aACpBL,KAAAS,eAAiB,IAAIJ,EAAAA,aACrBL,KAAAU,QAAU,IAAIL,EAAAA,aAQxBL,KAAAW,SAAmB,EAGnBX,KAAAY,iBAA2B,KAG3BZ,KAAAa,gBAA0B,UAC1Bb,KAAAc,6BAAuC,MAmH/Bd,KAAAe,cAAgBC,EAAAA,UAAS,WAE7B,GAAgC,GAA5BjB,EAAKG,KAAKjB,eAAyB,OAAO,EAE9C,IAAIgC,EAAkBlB,EAAKmB,uBAC3BnB,EAAKc,gBAAkB,KAAQI,EAAgBE,mBAAqB,EAAK,OAC1E,KAYKnB,KAAAoB,cAAgBJ,EAAAA,UAAS,WAAM,OAAAjB,EAAKsB,SAAQ,IAAK,CAACC,SAAW,EAAMC,UAAY,IAG/EvB,KAAAwB,cAAgBR,EAAAA,UAAS,WAAM,OAAAjB,EAAK0B,SAAQ,IAAK,CAACH,SAAW,EAAMC,UAAY,IAwJ3F,OA7RIG,OAAAC,eAAIjC,EAAAkC,UAAA,cAAW,KAAf,WACI,OAAO5B,KAAKG,OAAOH,KAAKY,mDAI5Bc,OAAAC,eAAIjC,EAAAkC,UAAA,eAAY,KAAhB,WACI,OAAgC,GAAzB5B,KAAKY,kDAIhBc,OAAAC,eAAIjC,EAAAkC,UAAA,cAAW,KAAf,WACI,OAAO5B,KAAKY,kBAAqBZ,KAAKG,OAAO0B,OAAS,mCAI1DH,OAAAC,eAAIjC,EAAAkC,UAAA,yBAAsB,KAA1B,WACI,IAYId,EAZAgB,EAA2B9B,KAAK+B,eAAeC,cAAcC,YAG7D3C,EADkB,GACgBU,KAAKE,KAAKZ,cAC5C4C,EAAmBC,KAAKC,MAAMN,EAA2BxC,GAIzD6B,EANkB,IAGgBW,EAA4BI,EAAmB5C,GACjC4C,EAGhDG,EAAmBlB,EAAqBnB,KAAKE,KAAKZ,cAKtD,GAHuD4C,GAAoBA,EAAmBlC,KAAKY,kBAG5CsB,EAAmB,EAAG,CACzE,IAAII,EAAkBtC,KAAKY,iBAAmB,EAAKsB,EAAoB,EAGnEpB,EADAd,KAAKY,kBAAqBZ,KAAKG,OAAO0B,OAAS,EAChB,IAAOQ,EAAmBC,EAAiB,KAG3C,IAAOD,GAAoBC,EAAgB,GAAM,UAGpFxB,EAA+B,MAGnC,MAAO,CACHoB,iBAAgBA,EAChBf,mBAAkBA,EAClBkB,iBAAgBA,EAChBvB,6BAA4BA,oCAK5BpB,EAAAkC,UAAAW,eAAR,SAAuBrC,GACnBF,KAAKE,KAAOsC,EAAAA,OAAO/D,EAAcyB,IAI7BR,EAAAkC,UAAAa,UAAR,SAAkBC,GAAlB,IAAA3C,EAAAC,KACU2C,EAA8B3C,KAAKG,OAAOuC,GAGhD,OAAIC,EAAaC,QACNC,QAAQC,QAAQJ,GAGhB,IAAIG,SAAQ,SAACC,EAASC,GACzBhD,EAAKY,SAAU,EAEf,IAAIqC,EAAQ,IAAIC,MAChBD,EAAME,IAAMP,EAAaQ,IAEzBH,EAAMI,OAAS,WACXrD,EAAKY,SAAU,EACfgC,EAAaC,SAAU,EACvBE,EAAQJ,IAGZM,EAAMK,QAAU,SAACC,GACbvD,EAAKY,SAAU,EACfoC,EAAOO,QAOf5D,EAAAkC,UAAA2B,cAAR,SAAsBC,GAAtB,IAAAzD,EAAAC,KAEI,GAAIA,KAAKW,QAAS,OAAO,EAGzBX,KAAKQ,cAAciD,KAAKD,GAExBxD,KAAKyC,UAAUe,GACVE,MAAK,SAAAC,GACF5D,EAAKa,iBAAmB+C,EAExB5D,EAAKD,MAAM8D,gBAGXC,YAAW,WACP9D,EAAKgB,gBACL8C,YAAW,WAAM,OAAA9D,EAAK+D,qBAAoB,WAGjDC,OAAM,SAAAT,GACHU,QAAQC,KAAKX,GACbvD,EAAKW,QAAQe,KAAK6B,OActB5D,EAAAkC,UAAAkC,iBAAR,WAEI,GAAgC,GAA5B9D,KAAKE,KAAKjB,eAAyB,OAAO,EAE9C,IAAIgC,EAAkBjB,KAAKkB,uBAC3BlB,KAAKc,6BAA+BG,EAAgBH,8BAkBxDpB,EAAAkC,UAAAsC,SAAA,WAEIlE,KAAKuC,eAAevC,KAAKE,MAGzBF,KAAKH,SAASsE,SAASnE,KAAKJ,YAAYoC,cAAe,mBAAoBhC,KAAKE,KAAKX,eAGjFS,KAAKE,KAAKV,SACVQ,KAAKH,SAASuE,SAASpE,KAAKJ,YAAYoC,cAAe,UACvDhC,KAAKqE,KAAK,KAIlB3E,EAAAkC,UAAA0C,YAAA,SAAYC,GAEJA,EAAQrE,MAAoC,GAA5BqE,EAAQrE,KAAKsE,cAC7BxE,KAAKuC,eAAegC,EAAQrE,KAAKuE,cAGjCzE,KAAKH,SAASsE,SAASnE,KAAKJ,YAAYoC,cAAe,mBAAoBhC,KAAKE,KAAKX,eAG3C,GAArCgF,EAAQrE,KAAKwE,cAAclF,QAAmBQ,KAAKE,KAAKV,SACzDQ,KAAKH,SAASuE,SAASpE,KAAKJ,YAAYoC,cAAe,UACvDhC,KAAKqE,KAAK,KAKdE,EAAQpE,QAAwC,GAA9BoE,EAAQpE,OAAOqE,cACjCxE,KAAKG,OAASoE,EAAQpE,OAAOsE,aAEzBzE,KAAKG,OAAO0B,QACZ7B,KAAKuD,cAAc,KAQxB7D,EAAAkC,UAAA+C,gBAAP,SAAuBC,GACf5E,KAAKE,KAAKf,iBAAmBa,KAAKC,SAAWD,KAAKW,UAClB,SAA5BtC,EAAUuG,EAAMC,SAChB7E,KAAKyB,OAE4B,QAA5BpD,EAAUuG,EAAMC,SACrB7E,KAAKqB,OAE6B,OAA5BhD,EAAUuG,EAAMC,UAAsB7E,KAAKE,KAAKhB,YACtDc,KAAK8E,UAOVpF,EAAAkC,UAAAmD,eAAP,SAAsBH,GADtB,IAAA7E,EAAAC,KAEQA,KAAKC,SAAWD,KAAKW,UACrBX,KAAKe,gBACL8C,YAAW,WAAM,OAAA9D,EAAK+D,qBAAoB,OAOlDpE,EAAAkC,UAAAyC,KAAA,SAAK3B,QAAA,IAAAA,IAAAA,EAAA,GACG1C,KAAKG,OAAO0B,QACZ7B,KAAKC,QAAS,EAGdD,KAAKI,OAAOqD,KAAKf,GAGjB1C,KAAKuD,cAAcb,IAGnBsB,QAAQC,KAAK,6CAKrBvE,EAAAkC,UAAAkD,MAAA,WACI9E,KAAKC,QAAS,EACdD,KAAKY,iBAAmB,EAGxBZ,KAAKM,QAAQmD,QAIjB/D,EAAAkC,UAAAP,KAAA,WAC6B,GAArBrB,KAAKgF,cACLhF,KAAKuD,cAAcvD,KAAKY,iBAAmB,IAKnDlB,EAAAkC,UAAAH,KAAA,WAC4B,GAApBzB,KAAKiF,aACLjF,KAAKuD,cAAcvD,KAAKY,iBAAmB,IAKnDlB,EAAAkC,UAAAsD,eAAA,SAAexC,GACX1C,KAAKuD,cAAcb,IAIvBhD,EAAAkC,UAAAuD,YAAA,SAAYzC,GACR1C,KAAKO,SAASkD,KAAKf,IAIvBhD,EAAAkC,UAAAwD,aAAA,WACQpF,KAAKE,KAAKd,mBACVY,KAAKwB,iBAKb9B,EAAAkC,UAAAyD,eAAA,WACQrF,KAAKE,KAAKd,mBACVY,KAAKoB,iBAKb1B,EAAAkC,UAAA0D,aAAA,SAAa5C,GACT1C,KAAKS,eAAegD,KAAKf,IAI7BhD,EAAAkC,UAAA2D,kBAAA,SAAkBX,GAEd,OADAA,EAAMY,kBACCxF,KAAKE,KAAKb,4DAhJCoG,EAAAA,oBACGC,EAAAA,kBACHC,EAAAA,iBACHC,EAAAA,qBA7KUC,EAAAA,WAAAA,CAA5BC,EAAAA,YAAY,8CAGJD,EAAAA,WAAAA,CAARE,EAAAA,oCAGQF,EAAAA,WAAAA,CAARE,EAAAA,sCAGSF,EAAAA,WAAAA,CAATG,EAAAA,uCACSH,EAAAA,WAAAA,CAATG,EAAAA,wCACSH,EAAAA,WAAAA,CAATG,EAAAA,yCACSH,EAAAA,WAAAA,CAATG,EAAAA,8CACSH,EAAAA,WAAAA,CAATG,EAAAA,+CACSH,EAAAA,WAAAA,CAATG,EAAAA,wCAGwBH,EAAAA,WAAAA,CAAxBI,EAAAA,UAAU,oDAyMXJ,EAAAA,WAAAA,CADCK,EAAAA,aAAa,iBAAkB,CAAC,gDAiBjCL,EAAAA,WAAAA,CADCK,EAAAA,aAAa,gBAAiB,CAAC,+CA5OvBxG,EAAwByG,EAAAN,WAAA,CALpCO,EAAAA,UAAU,CACPC,SAAU,oBACVC,SAAA,i43BAGS5G,mBC7CX,SAAA6G,EAAoBC,GAAAxG,KAAAwG,YAAAA,EAFVxG,KAAAyG,aAAkC,IAAIpG,EAAAA,aAWlD,OANSkG,EAAA3E,UAAA8E,QAAP,SAAeC,EAAQC,GACG5G,KAAKwG,YAAYxE,cAAc6E,SAASD,IAE9D5G,KAAKyG,aAAahD,KAAKkD,6CANMjB,EAAAA,cAFvBG,EAAAA,WAAAA,CAATG,EAAAA,6CAKDH,EAAAA,WAAAA,CADCK,EAAAA,aAAa,iBAAkB,CAAC,SAAU,+CALhCK,EAAqBJ,EAAAN,WAAA,CAHjCiB,EAAAA,UAAU,CACTT,SAAU,oBAECE,mBCFb,SAAAQ,IACY/G,KAAAoF,aAAe,IAAI/E,EAAAA,aACnBL,KAAAqF,eAAiB,IAAIhF,EAAAA,aA6BjC,OA3B0C0G,EAAAnF,UAAAoF,mBAAA,SAAmBpC,GACzD5E,KAAKiH,eAAerC,IAGsBmC,EAAAnF,UAAAsF,oBAAA,SAAoBtC,GAC9D5E,KAAKiH,eAAerC,IAGoBmC,EAAAnF,UAAAuF,eAAA,SAAevC,GACvD5E,KAAKiH,eAAerC,IAGtBmC,EAAAnF,UAAAqF,eAAA,SAAerC,GACTA,EAAQwC,OAAOxC,OAASA,EAA5B,IACIyC,EAAQlF,KAAKmF,KAAK,EAAGnF,KAAKoF,IAAI,EAAI3C,EAAM4C,aAAe5C,EAAM6C,SAC9DJ,EAAQ,EACPrH,KAAKoF,aAAa3B,KAAKmB,GACjByC,EAAQ,GACdrH,KAAKqF,eAAe5B,KAAKmB,GAG7BA,EAAM8C,aAAc,EAEjB9C,EAAM+C,gBACL/C,EAAM+C,kBA3BF9B,EAAAA,WAAAA,CAATG,EAAAA,6CACSH,EAAAA,WAAAA,CAATG,EAAAA,+CAEuCH,EAAAA,WAAAA,CAAvCK,EAAAA,aAAa,aAAc,CAAC,mDAIeL,EAAAA,WAAAA,CAA3CK,EAAAA,aAAa,iBAAkB,CAAC,oDAISL,EAAAA,WAAAA,CAAzCK,EAAAA,aAAa,eAAgB,CAAC,+CAZpBa,EAAmBZ,EAAAN,WAAA,CAD/BiB,EAAAA,UAAU,CAAET,SAAU,kBACVU,mBCwBb,SAAAa,KACA,OADaA,EAAqBzB,EAAAN,WAAA,CAfjCgC,EAAAA,SAAS,CACNC,QAAS,CACLC,EAAAA,cAEJC,aAAc,CACVtI,EACAqH,EACAR,GAEJ0B,QAAS,CACLvI,EACAqH,EACAR,MAGKqB","sourcesContent":["import {\n Component,\n OnInit,\n HostBinding,\n Input,\n HostListener,\n ElementRef,\n Renderer2,\n EventEmitter,\n Output,\n OnChanges,\n SimpleChanges,\n ViewChild,\n ChangeDetectorRef\n} from '@angular/core';\n\nimport {assign, debounce} from 'lodash';\n\nimport {GALLERY_CONF, GALLERY_IMAGE} from '../../ngx-image-gallery.conf';\nimport { DomSanitizer } from '@angular/platform-browser';\n\n// key codes to react\nconst KEY_CODES = {\n 37: 'LEFT',\n 39: 'RIGHT',\n 27: 'ESC'\n};\n\n// default gallery configuration\nconst DEFAULT_CONF: GALLERY_CONF = {\n imageBorderRadius: '3px',\n imageOffset: '20px',\n imagePointer: false,\n showDeleteControl: false,\n showCloseControl: true,\n showExtUrlControl: true,\n showImageTitle: true,\n showThumbnails: true,\n closeOnEsc: true,\n reactToKeyboard: true,\n reactToMouseWheel: true,\n reactToRightClick: false,\n thumbnailSize: 30,\n backdropColor: 'rgba(13,13,14,0.85)',\n inline: false,\n showArrows: true\n};\n\n@Component({\n selector: 'ngx-image-gallery',\n templateUrl: './ngx-image-gallery.component.html',\n styleUrls: ['./ngx-image-gallery.component.scss']\n})\nexport class NgxImageGalleryComponent implements OnInit, OnChanges {\n\n // gallery opened memory\n @HostBinding('class.active') opened: boolean = false;\n\n // gallery configuration\n @Input() conf: GALLERY_CONF = {};\n\n // gallery images\n @Input() images: GALLERY_IMAGE[] = [];\n\n // event emmiters\n @Output() onOpen = new EventEmitter();\n @Output() onClose = new EventEmitter();\n @Output() onDelete = new EventEmitter();\n @Output() onImageChange = new EventEmitter();\n @Output() onImageClicked = new EventEmitter();\n @Output() onError = new EventEmitter();\n\n // thumbnails container\n @ViewChild('thumbnails') thumbnailsElem: ElementRef;\n\n /***************************************************/\n\n // loading animation memory\n loading: boolean = false;\n\n // current active image index\n activeImageIndex: number = null;\n\n // thumbnail margin and scroll position\n thumbnailMargin: string = '0px 8px';\n thumbnailsScrollerLeftMargin: string = '0px';\n\n // active image\n get activeImage(): GALLERY_IMAGE {\n return this.images[this.activeImageIndex];\n }\n\n // if gallery is on : first image\n get onFirstImage(): boolean {\n return this.activeImageIndex == 0;\n }\n\n // if gallery is on : last image\n get onLastImage(): boolean {\n return this.activeImageIndex == (this.images.length - 1);\n }\n\n // get thumbnails viewport rendering parameters\n get thumbnailsRenderParams(): { thumbnailsInView: number, newThumbnailMargin: number, newThumbnailSize: number, thumbnailsScrollerLeftMargin: any } {\n let thumbnailsContainerWidth = this.thumbnailsElem.nativeElement.offsetWidth;\n\n let thumbnailMargin = 16;\n let thumbnailSize = thumbnailMargin + this.conf.thumbnailSize;\n let thumbnailsInView = Math.floor(thumbnailsContainerWidth / thumbnailSize);\n let extraSpaceInThumbnailsContainer = thumbnailsContainerWidth - (thumbnailsInView * thumbnailSize);\n let extraMargin = extraSpaceInThumbnailsContainer / thumbnailsInView;\n\n let newThumbnailMargin = thumbnailMargin + extraMargin;\n let newThumbnailSize = newThumbnailMargin + this.conf.thumbnailSize;\n\n let relativePositionOfActiveImageThumbnailToScroller = thumbnailsInView - (thumbnailsInView - this.activeImageIndex);\n let thumbnailsScrollerLeftMargin: any;\n\n if (relativePositionOfActiveImageThumbnailToScroller > thumbnailsInView - 2) {\n var outThumbnails = ((this.activeImageIndex + 1) - thumbnailsInView) + 1;\n\n if (this.activeImageIndex != (this.images.length - 1)) {\n thumbnailsScrollerLeftMargin = '-' + (newThumbnailSize * outThumbnails) + 'px';\n }\n else {\n thumbnailsScrollerLeftMargin = '-' + (newThumbnailSize * (outThumbnails - 1)) + 'px';\n }\n } else {\n thumbnailsScrollerLeftMargin = '0px';\n }\n\n return {\n thumbnailsInView,\n newThumbnailMargin,\n newThumbnailSize,\n thumbnailsScrollerLeftMargin\n };\n }\n\n // set gallery configuration\n private setGalleryConf(conf: GALLERY_CONF) {\n this.conf = assign(DEFAULT_CONF, conf);\n }\n\n // load image and return promise\n private loadImage(index: number): Promise {\n const galleryImage: GALLERY_IMAGE = this.images[index];\n\n // check if image is cached\n if (galleryImage._cached) {\n return Promise.resolve(index);\n }\n else {\n return new Promise((resolve, reject) => {\n this.loading = true;\n\n let image = new Image();\n image.src = galleryImage.url;\n\n image.onload = () => {\n this.loading = false;\n galleryImage._cached = true;\n resolve(index);\n };\n\n image.onerror = (error) => {\n this.loading = false;\n reject(error);\n };\n });\n }\n }\n\n // activate image (set active image)\n private activateImage(imageIndex: number) {\n // prevent loading if already loading\n if (this.loading) return false;\n\n // emit event\n this.onImageChange.emit(imageIndex);\n\n this.loadImage(imageIndex)\n .then(_imageIndex => {\n this.activeImageIndex = _imageIndex;\n // Trigger change detection manually to support ChangeDetectionStrategy.OnPush\n this.cdRef.detectChanges();\n\n // scroll thumbnails\n setTimeout(() => {\n this.fitThumbnails();\n setTimeout(() => this.scrollThumbnails(), 300);\n });\n })\n .catch(error => {\n console.warn(error)\n this.onError.next(error);\n });\n }\n\n // adjust thumbnail margin to perfectly fit viewport\n private fitThumbnails = debounce(() => {\n // if thumbnails not visible, return false\n if (this.conf.showThumbnails == false) return false;\n\n let thumbnailParams = this.thumbnailsRenderParams;\n this.thumbnailMargin = '0 ' + (thumbnailParams.newThumbnailMargin / 2) + 'px';\n }, 300);\n\n // scroll thumbnails to perfectly position active image thumbnail in viewport\n private scrollThumbnails() {\n // if thumbnails not visible, return false\n if (this.conf.showThumbnails == false) return false;\n\n let thumbnailParams = this.thumbnailsRenderParams;\n this.thumbnailsScrollerLeftMargin = thumbnailParams.thumbnailsScrollerLeftMargin;\n }\n\n // debounced prev\n private debouncedPrev = debounce(() => this.prev(), 100, {'leading': true, 'trailing': false});\n\n // debounced next\n private debouncedNext = debounce(() => this.next(), 100, {'leading': true, 'trailing': false});\n\n /***************************************************/\n\n constructor(\n public sanitizer: DomSanitizer,\n private galleryElem: ElementRef,\n private renderer: Renderer2,\n private cdRef: ChangeDetectorRef\n ) {}\n\n ngOnInit() {\n // create final gallery configuration\n this.setGalleryConf(this.conf);\n\n // apply backdrop color\n this.renderer.setStyle(this.galleryElem.nativeElement, 'background-color', this.conf.backdropColor);\n\n // gallery inline class and auto open\n if (this.conf.inline) {\n this.renderer.addClass(this.galleryElem.nativeElement, 'inline');\n this.open(0);\n }\n }\n\n ngOnChanges(changes: SimpleChanges) {\n // when gallery configuration changes\n if (changes.conf && changes.conf.firstChange == false) {\n this.setGalleryConf(changes.conf.currentValue);\n\n // apply backdrop color\n this.renderer.setStyle(this.galleryElem.nativeElement, 'background-color', this.conf.backdropColor);\n\n // gallery inline class and auto open\n if ((changes.conf.previousValue.inline != true) && this.conf.inline) {\n this.renderer.addClass(this.galleryElem.nativeElement, 'inline');\n this.open(0);\n }\n }\n\n // when gallery images changes\n if (changes.images && changes.images.firstChange == false) {\n this.images = changes.images.currentValue;\n\n if (this.images.length) {\n this.activateImage(0);\n }\n }\n\n }\n\n // keyboard event\n @HostListener('window:keydown', ['$event'])\n public onKeyboardInput(event: KeyboardEvent) {\n if (this.conf.reactToKeyboard && this.opened && !this.loading) {\n if (KEY_CODES[event.keyCode] == 'RIGHT') {\n this.next();\n }\n else if (KEY_CODES[event.keyCode] == 'LEFT') {\n this.prev();\n }\n else if ((KEY_CODES[event.keyCode] == 'ESC') && this.conf.closeOnEsc) {\n this.close();\n }\n }\n }\n\n // window resize event\n @HostListener('window:resize', ['$event'])\n public onWindowResize(event: Event) {\n if (this.opened && !this.loading) {\n this.fitThumbnails();\n setTimeout(() => this.scrollThumbnails(), 300);\n }\n }\n\n /***************************************************/\n\n // open gallery\n open(index: number = 0) {\n if (this.images.length) {\n this.opened = true;\n\n // emit event\n this.onOpen.emit(index);\n\n // activate image at given index\n this.activateImage(index);\n }\n else {\n console.warn('No images provided to ngx-image-gallery!');\n }\n }\n\n // close gallery\n close() {\n this.opened = false;\n this.activeImageIndex = 0;\n\n // emit event\n this.onClose.emit();\n }\n\n // change prev image\n prev() {\n if (this.onFirstImage == false) {\n this.activateImage(this.activeImageIndex - 1);\n }\n }\n\n // change next image\n next() {\n if (this.onLastImage == false) {\n this.activateImage(this.activeImageIndex + 1);\n }\n }\n\n // set image (activate)\n setActiveImage(index: number) {\n this.activateImage(index);\n }\n\n // delete image\n deleteImage(index: number) {\n this.onDelete.emit(index);\n }\n\n // mouse wheel up (prev image)\n mouseWheelUp() {\n if (this.conf.reactToMouseWheel) {\n this.debouncedNext();\n }\n }\n\n // mouse wheel down (next image)\n mouseWheelDown() {\n if (this.conf.reactToMouseWheel) {\n this.debouncedPrev();\n }\n }\n\n // click on image\n clickOnImage(index: number) {\n this.onImageClicked.emit(index);\n }\n\n // right click on image\n rightClickOnImage(event: Event) {\n event.stopPropagation();\n return this.conf.reactToRightClick;\n }\n\n}\n","import { Directive, ElementRef, Output, EventEmitter, HostListener } from '@angular/core';\n\n@Directive({\n selector: '[clickOutside]'\n})\nexport class ClickOutsideDirective {\n @Output() clickOutside: EventEmitter = new EventEmitter();\n\n constructor(private _elementRef: ElementRef) {}\n\n @HostListener('document:click', ['$event', '$event.target'])\n public onClick($event, targetElement) {\n const isClickedInside = this._elementRef.nativeElement.contains(targetElement);\n if (!isClickedInside) {\n this.clickOutside.emit($event);\n }\n }\n}","import { Directive, Output, HostListener, EventEmitter } from '@angular/core';\n\n@Directive({ selector: '[mouseWheel]' })\nexport class MouseWheelDirective {\n @Output() mouseWheelUp = new EventEmitter();\n @Output() mouseWheelDown = new EventEmitter();\n\n @HostListener('mousewheel', ['$event']) onMouseWheelChrome(event: any) {\n this.mouseWheelFunc(event);\n }\n\n @HostListener('DOMMouseScroll', ['$event']) onMouseWheelFirefox(event: any) {\n this.mouseWheelFunc(event);\n }\n\n @HostListener('onmousewheel', ['$event']) onMouseWheelIE(event: any) {\n this.mouseWheelFunc(event);\n }\n\n mouseWheelFunc(event: any) {\n var event = window.event || event; // old IE support\n var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail)));\n if(delta > 0) {\n this.mouseWheelUp.emit(event);\n } else if(delta < 0) {\n this.mouseWheelDown.emit(event);\n }\n // for IE\n event.returnValue = false;\n // for Chrome and Firefox\n if(event.preventDefault) {\n event.preventDefault();\n }\n }\n}","import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\n\nimport {NgxImageGalleryComponent} from './components/ngx-image-gallery/ngx-image-gallery.component';\nimport {ClickOutsideDirective} from './directives/click-outside.directive';\nimport {MouseWheelDirective} from './directives/mousewheel.directive';\n\nexport * from './components/ngx-image-gallery/ngx-image-gallery.component';\nexport * from './directives/click-outside.directive';\nexport * from './directives/mousewheel.directive';\nexport * from './ngx-image-gallery.conf';\n\n@NgModule({\n imports: [\n CommonModule\n ],\n declarations: [\n NgxImageGalleryComponent,\n MouseWheelDirective,\n ClickOutsideDirective\n ],\n exports: [\n NgxImageGalleryComponent,\n MouseWheelDirective,\n ClickOutsideDirective\n ]\n})\nexport class NgxImageGalleryModule {\n}\n"]} -------------------------------------------------------------------------------- /dist/ngx-image-gallery/esm2015/lib/directives/click-outside.directive.js: -------------------------------------------------------------------------------- 1 | import { __decorate } from "tslib"; 2 | import { Directive, ElementRef, Output, EventEmitter, HostListener } from '@angular/core'; 3 | let ClickOutsideDirective = class ClickOutsideDirective { 4 | constructor(_elementRef) { 5 | this._elementRef = _elementRef; 6 | this.clickOutside = new EventEmitter(); 7 | } 8 | onClick($event, targetElement) { 9 | const isClickedInside = this._elementRef.nativeElement.contains(targetElement); 10 | if (!isClickedInside) { 11 | this.clickOutside.emit($event); 12 | } 13 | } 14 | }; 15 | ClickOutsideDirective.ctorParameters = () => [ 16 | { type: ElementRef } 17 | ]; 18 | __decorate([ 19 | Output() 20 | ], ClickOutsideDirective.prototype, "clickOutside", void 0); 21 | __decorate([ 22 | HostListener('document:click', ['$event', '$event.target']) 23 | ], ClickOutsideDirective.prototype, "onClick", null); 24 | ClickOutsideDirective = __decorate([ 25 | Directive({ 26 | selector: '[clickOutside]' 27 | }) 28 | ], ClickOutsideDirective); 29 | export { ClickOutsideDirective }; 30 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpY2stb3V0c2lkZS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtaW1hZ2UtZ2FsbGVyeS8iLCJzb3VyY2VzIjpbImxpYi9kaXJlY3RpdmVzL2NsaWNrLW91dHNpZGUuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUsxRixJQUFhLHFCQUFxQixHQUFsQyxNQUFhLHFCQUFxQjtJQUdoQyxZQUFvQixXQUF1QjtRQUF2QixnQkFBVyxHQUFYLFdBQVcsQ0FBWTtRQUZqQyxpQkFBWSxHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDO0lBRWpCLENBQUM7SUFHeEMsT0FBTyxDQUFDLE1BQU0sRUFBRSxhQUFhO1FBQ2xDLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUMvRSxJQUFJLENBQUMsZUFBZSxFQUFFO1lBQ3BCLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQ2hDO0lBQ0gsQ0FBQztDQUNGLENBQUE7O1lBVGtDLFVBQVU7O0FBRmpDO0lBQVQsTUFBTSxFQUFFOzJEQUFzRDtBQUsvRDtJQURDLFlBQVksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsRUFBRSxlQUFlLENBQUMsQ0FBQztvREFNM0Q7QUFYVSxxQkFBcUI7SUFIakMsU0FBUyxDQUFDO1FBQ1QsUUFBUSxFQUFFLGdCQUFnQjtLQUMzQixDQUFDO0dBQ1cscUJBQXFCLENBWWpDO1NBWlkscUJBQXFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tjbGlja091dHNpZGVdJ1xufSlcbmV4cG9ydCBjbGFzcyBDbGlja091dHNpZGVEaXJlY3RpdmUge1xuICBAT3V0cHV0KCkgY2xpY2tPdXRzaWRlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmKSB7fVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQnLCAnJGV2ZW50LnRhcmdldCddKVxuICBwdWJsaWMgb25DbGljaygkZXZlbnQsIHRhcmdldEVsZW1lbnQpIHtcbiAgICBjb25zdCBpc0NsaWNrZWRJbnNpZGUgPSB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnModGFyZ2V0RWxlbWVudCk7XG4gICAgaWYgKCFpc0NsaWNrZWRJbnNpZGUpIHtcbiAgICAgIHRoaXMuY2xpY2tPdXRzaWRlLmVtaXQoJGV2ZW50KTtcbiAgICB9XG4gIH1cbn0iXX0= -------------------------------------------------------------------------------- /dist/ngx-image-gallery/esm2015/lib/directives/mousewheel.directive.js: -------------------------------------------------------------------------------- 1 | import { __decorate } from "tslib"; 2 | import { Directive, Output, HostListener, EventEmitter } from '@angular/core'; 3 | let MouseWheelDirective = class MouseWheelDirective { 4 | constructor() { 5 | this.mouseWheelUp = new EventEmitter(); 6 | this.mouseWheelDown = new EventEmitter(); 7 | } 8 | onMouseWheelChrome(event) { 9 | this.mouseWheelFunc(event); 10 | } 11 | onMouseWheelFirefox(event) { 12 | this.mouseWheelFunc(event); 13 | } 14 | onMouseWheelIE(event) { 15 | this.mouseWheelFunc(event); 16 | } 17 | mouseWheelFunc(event) { 18 | var event = window.event || event; // old IE support 19 | var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail))); 20 | if (delta > 0) { 21 | this.mouseWheelUp.emit(event); 22 | } 23 | else if (delta < 0) { 24 | this.mouseWheelDown.emit(event); 25 | } 26 | // for IE 27 | event.returnValue = false; 28 | // for Chrome and Firefox 29 | if (event.preventDefault) { 30 | event.preventDefault(); 31 | } 32 | } 33 | }; 34 | __decorate([ 35 | Output() 36 | ], MouseWheelDirective.prototype, "mouseWheelUp", void 0); 37 | __decorate([ 38 | Output() 39 | ], MouseWheelDirective.prototype, "mouseWheelDown", void 0); 40 | __decorate([ 41 | HostListener('mousewheel', ['$event']) 42 | ], MouseWheelDirective.prototype, "onMouseWheelChrome", null); 43 | __decorate([ 44 | HostListener('DOMMouseScroll', ['$event']) 45 | ], MouseWheelDirective.prototype, "onMouseWheelFirefox", null); 46 | __decorate([ 47 | HostListener('onmousewheel', ['$event']) 48 | ], MouseWheelDirective.prototype, "onMouseWheelIE", null); 49 | MouseWheelDirective = __decorate([ 50 | Directive({ selector: '[mouseWheel]' }) 51 | ], MouseWheelDirective); 52 | export { MouseWheelDirective }; 53 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW91c2V3aGVlbC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtaW1hZ2UtZ2FsbGVyeS8iLCJzb3VyY2VzIjpbImxpYi9kaXJlY3RpdmVzL21vdXNld2hlZWwuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRzlFLElBQWEsbUJBQW1CLEdBQWhDLE1BQWEsbUJBQW1CO0lBQWhDO1FBQ1ksaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ2xDLG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQTZCaEQsQ0FBQztJQTNCeUMsa0JBQWtCLENBQUMsS0FBVTtRQUNuRSxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFFMkMsbUJBQW1CLENBQUMsS0FBVTtRQUN4RSxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFFeUMsY0FBYyxDQUFDLEtBQVU7UUFDakUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBRUQsY0FBYyxDQUFDLEtBQVU7UUFDdkIsSUFBSSxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsQ0FBQyxpQkFBaUI7UUFDcEQsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxVQUFVLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNFLElBQUcsS0FBSyxHQUFHLENBQUMsRUFBRTtZQUNWLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ2pDO2FBQU0sSUFBRyxLQUFLLEdBQUcsQ0FBQyxFQUFFO1lBQ2pCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ25DO1FBQ0QsU0FBUztRQUNULEtBQUssQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO1FBQzFCLHlCQUF5QjtRQUN6QixJQUFHLEtBQUssQ0FBQyxjQUFjLEVBQUU7WUFDckIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1NBQzFCO0lBQ0gsQ0FBQztDQUNGLENBQUE7QUE5Qlc7SUFBVCxNQUFNLEVBQUU7eURBQW1DO0FBQ2xDO0lBQVQsTUFBTSxFQUFFOzJEQUFxQztBQUVOO0lBQXZDLFlBQVksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQzs2REFFdEM7QUFFMkM7SUFBM0MsWUFBWSxDQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7OERBRTFDO0FBRXlDO0lBQXpDLFlBQVksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQzt5REFFeEM7QUFkVSxtQkFBbUI7SUFEL0IsU0FBUyxDQUFDLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxDQUFDO0dBQzNCLG1CQUFtQixDQStCL0I7U0EvQlksbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBPdXRwdXQsIEhvc3RMaXN0ZW5lciwgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ1ttb3VzZVdoZWVsXScgfSlcbmV4cG9ydCBjbGFzcyBNb3VzZVdoZWVsRGlyZWN0aXZlIHtcbiAgQE91dHB1dCgpIG1vdXNlV2hlZWxVcCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIG1vdXNlV2hlZWxEb3duID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNld2hlZWwnLCBbJyRldmVudCddKSBvbk1vdXNlV2hlZWxDaHJvbWUoZXZlbnQ6IGFueSkge1xuICAgIHRoaXMubW91c2VXaGVlbEZ1bmMoZXZlbnQpO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignRE9NTW91c2VTY3JvbGwnLCBbJyRldmVudCddKSBvbk1vdXNlV2hlZWxGaXJlZm94KGV2ZW50OiBhbnkpIHtcbiAgICB0aGlzLm1vdXNlV2hlZWxGdW5jKGV2ZW50KTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ29ubW91c2V3aGVlbCcsIFsnJGV2ZW50J10pIG9uTW91c2VXaGVlbElFKGV2ZW50OiBhbnkpIHtcbiAgICB0aGlzLm1vdXNlV2hlZWxGdW5jKGV2ZW50KTtcbiAgfVxuXG4gIG1vdXNlV2hlZWxGdW5jKGV2ZW50OiBhbnkpIHtcbiAgICB2YXIgZXZlbnQgPSB3aW5kb3cuZXZlbnQgfHwgZXZlbnQ7IC8vIG9sZCBJRSBzdXBwb3J0XG4gICAgdmFyIGRlbHRhID0gTWF0aC5tYXgoLTEsIE1hdGgubWluKDEsIChldmVudC53aGVlbERlbHRhIHx8IC1ldmVudC5kZXRhaWwpKSk7XG4gICAgaWYoZGVsdGEgPiAwKSB7XG4gICAgICAgIHRoaXMubW91c2VXaGVlbFVwLmVtaXQoZXZlbnQpO1xuICAgIH0gZWxzZSBpZihkZWx0YSA8IDApIHtcbiAgICAgICAgdGhpcy5tb3VzZVdoZWVsRG93bi5lbWl0KGV2ZW50KTtcbiAgICB9XG4gICAgLy8gZm9yIElFXG4gICAgZXZlbnQucmV0dXJuVmFsdWUgPSBmYWxzZTtcbiAgICAvLyBmb3IgQ2hyb21lIGFuZCBGaXJlZm94XG4gICAgaWYoZXZlbnQucHJldmVudERlZmF1bHQpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH1cbn0iXX0= -------------------------------------------------------------------------------- /dist/ngx-image-gallery/esm2015/lib/index.js: -------------------------------------------------------------------------------- 1 | import { __decorate } from "tslib"; 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { NgxImageGalleryComponent } from './components/ngx-image-gallery/ngx-image-gallery.component'; 5 | import { ClickOutsideDirective } from './directives/click-outside.directive'; 6 | import { MouseWheelDirective } from './directives/mousewheel.directive'; 7 | export * from './components/ngx-image-gallery/ngx-image-gallery.component'; 8 | export * from './directives/click-outside.directive'; 9 | export * from './directives/mousewheel.directive'; 10 | let NgxImageGalleryModule = class NgxImageGalleryModule { 11 | }; 12 | NgxImageGalleryModule = __decorate([ 13 | NgModule({ 14 | imports: [ 15 | CommonModule 16 | ], 17 | declarations: [ 18 | NgxImageGalleryComponent, 19 | MouseWheelDirective, 20 | ClickOutsideDirective 21 | ], 22 | exports: [ 23 | NgxImageGalleryComponent, 24 | MouseWheelDirective, 25 | ClickOutsideDirective 26 | ] 27 | }) 28 | ], NgxImageGalleryModule); 29 | export { NgxImageGalleryModule }; 30 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtaW1hZ2UtZ2FsbGVyeS8iLCJzb3VyY2VzIjpbImxpYi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUN2QyxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFFN0MsT0FBTyxFQUFDLHdCQUF3QixFQUFDLE1BQU0sNERBQTRELENBQUM7QUFDcEcsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sc0NBQXNDLENBQUM7QUFDM0UsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sbUNBQW1DLENBQUM7QUFFdEUsY0FBYyw0REFBNEQsQ0FBQztBQUMzRSxjQUFjLHNDQUFzQyxDQUFDO0FBQ3JELGNBQWMsbUNBQW1DLENBQUM7QUFrQmxELElBQWEscUJBQXFCLEdBQWxDLE1BQWEscUJBQXFCO0NBQ2pDLENBQUE7QUFEWSxxQkFBcUI7SUFmakMsUUFBUSxDQUFDO1FBQ04sT0FBTyxFQUFFO1lBQ0wsWUFBWTtTQUNmO1FBQ0QsWUFBWSxFQUFFO1lBQ1Ysd0JBQXdCO1lBQ3hCLG1CQUFtQjtZQUNuQixxQkFBcUI7U0FDeEI7UUFDRCxPQUFPLEVBQUU7WUFDTCx3QkFBd0I7WUFDeEIsbUJBQW1CO1lBQ25CLHFCQUFxQjtTQUN4QjtLQUNKLENBQUM7R0FDVyxxQkFBcUIsQ0FDakM7U0FEWSxxQkFBcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge05nTW9kdWxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7Q29tbW9uTW9kdWxlfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuXG5pbXBvcnQge05neEltYWdlR2FsbGVyeUNvbXBvbmVudH0gZnJvbSAnLi9jb21wb25lbnRzL25neC1pbWFnZS1nYWxsZXJ5L25neC1pbWFnZS1nYWxsZXJ5LmNvbXBvbmVudCc7XG5pbXBvcnQge0NsaWNrT3V0c2lkZURpcmVjdGl2ZX0gZnJvbSAnLi9kaXJlY3RpdmVzL2NsaWNrLW91dHNpZGUuZGlyZWN0aXZlJztcbmltcG9ydCB7TW91c2VXaGVlbERpcmVjdGl2ZX0gZnJvbSAnLi9kaXJlY3RpdmVzL21vdXNld2hlZWwuZGlyZWN0aXZlJztcblxuZXhwb3J0ICogZnJvbSAnLi9jb21wb25lbnRzL25neC1pbWFnZS1nYWxsZXJ5L25neC1pbWFnZS1nYWxsZXJ5LmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL2RpcmVjdGl2ZXMvY2xpY2stb3V0c2lkZS5kaXJlY3RpdmUnO1xuZXhwb3J0ICogZnJvbSAnLi9kaXJlY3RpdmVzL21vdXNld2hlZWwuZGlyZWN0aXZlJztcbmV4cG9ydCAqIGZyb20gJy4vbmd4LWltYWdlLWdhbGxlcnkuY29uZic7XG5cbkBOZ01vZHVsZSh7XG4gICAgaW1wb3J0czogW1xuICAgICAgICBDb21tb25Nb2R1bGVcbiAgICBdLFxuICAgIGRlY2xhcmF0aW9uczogW1xuICAgICAgICBOZ3hJbWFnZUdhbGxlcnlDb21wb25lbnQsXG4gICAgICAgIE1vdXNlV2hlZWxEaXJlY3RpdmUsXG4gICAgICAgIENsaWNrT3V0c2lkZURpcmVjdGl2ZVxuICAgIF0sXG4gICAgZXhwb3J0czogW1xuICAgICAgICBOZ3hJbWFnZUdhbGxlcnlDb21wb25lbnQsXG4gICAgICAgIE1vdXNlV2hlZWxEaXJlY3RpdmUsXG4gICAgICAgIENsaWNrT3V0c2lkZURpcmVjdGl2ZVxuICAgIF1cbn0pXG5leHBvcnQgY2xhc3MgTmd4SW1hZ2VHYWxsZXJ5TW9kdWxlIHtcbn1cbiJdfQ== -------------------------------------------------------------------------------- /dist/ngx-image-gallery/esm2015/lib/ngx-image-gallery.conf.js: -------------------------------------------------------------------------------- 1 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWltYWdlLWdhbGxlcnkuY29uZi5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1pbWFnZS1nYWxsZXJ5LyIsInNvdXJjZXMiOlsibGliL25neC1pbWFnZS1nYWxsZXJ5LmNvbmYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBpbnRlcmZhY2UgR0FMTEVSWV9DT05GIHtcblx0aW1hZ2VCb3JkZXJSYWRpdXM/OiBzdHJpbmc7XG4gICAgaW1hZ2VPZmZzZXQ/OiBzdHJpbmc7XG4gICAgaW1hZ2VQb2ludGVyPyA6Ym9vbGVhbjtcbiAgICBzaG93RGVsZXRlQ29udHJvbD86IGJvb2xlYW47XG5cdHNob3dDbG9zZUNvbnRyb2w/OiBib29sZWFuO1xuXHRzaG93RXh0VXJsQ29udHJvbD86IGJvb2xlYW47XG5cdHNob3dBcnJvd3M/OiBib29sZWFuO1xuXHRzaG93SW1hZ2VUaXRsZT86IGJvb2xlYW47XG5cdHNob3dUaHVtYm5haWxzPzogYm9vbGVhbjtcblx0Y2xvc2VPbkVzYz86IGJvb2xlYW47XG5cdHJlYWN0VG9LZXlib2FyZD86IGJvb2xlYW47XG5cdHJlYWN0VG9Nb3VzZVdoZWVsPzogYm9vbGVhbjtcblx0cmVhY3RUb1JpZ2h0Q2xpY2s/OiBib29sZWFuO1xuXHR0aHVtYm5haWxTaXplPzogbnVtYmVyO1xuXHRiYWNrZHJvcENvbG9yPzogc3RyaW5nO1xuXHRpbmxpbmU/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdBTExFUllfSU1BR0Uge1xuXHRfY2FjaGVkPzogYm9vbGVhbjtcblx0dXJsOiBzdHJpbmc7XG5cdHRodW1ibmFpbFVybD86IHN0cmluZztcblx0YWx0VGV4dD86IHN0cmluZztcblx0dGl0bGU/OiBzdHJpbmc7XG5cdGV4dFVybD86IHN0cmluZztcblx0ZXh0VXJsVGFyZ2V0Pzogc3RyaW5nO1xufSJdfQ== -------------------------------------------------------------------------------- /dist/ngx-image-gallery/esm2015/ngx-image-gallery.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generated bundle index. Do not edit. 3 | */ 4 | export * from './public-api'; 5 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWltYWdlLWdhbGxlcnkuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtaW1hZ2UtZ2FsbGVyeS8iLCJzb3VyY2VzIjpbIm5neC1pbWFnZS1nYWxsZXJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vcHVibGljLWFwaSc7XG4iXX0= -------------------------------------------------------------------------------- /dist/ngx-image-gallery/esm2015/public-api.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Public API Surface of ngx-image-gallery 3 | */ 4 | export * from './lib/index'; 5 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1pbWFnZS1nYWxsZXJ5LyIsInNvdXJjZXMiOlsicHVibGljLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILGNBQWMsYUFBYSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIFB1YmxpYyBBUEkgU3VyZmFjZSBvZiBuZ3gtaW1hZ2UtZ2FsbGVyeVxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vbGliL2luZGV4JztcbiJdfQ== -------------------------------------------------------------------------------- /dist/ngx-image-gallery/esm5/lib/directives/click-outside.directive.js: -------------------------------------------------------------------------------- 1 | import { __decorate } from "tslib"; 2 | import { Directive, ElementRef, Output, EventEmitter, HostListener } from '@angular/core'; 3 | var ClickOutsideDirective = /** @class */ (function () { 4 | function ClickOutsideDirective(_elementRef) { 5 | this._elementRef = _elementRef; 6 | this.clickOutside = new EventEmitter(); 7 | } 8 | ClickOutsideDirective.prototype.onClick = function ($event, targetElement) { 9 | var isClickedInside = this._elementRef.nativeElement.contains(targetElement); 10 | if (!isClickedInside) { 11 | this.clickOutside.emit($event); 12 | } 13 | }; 14 | ClickOutsideDirective.ctorParameters = function () { return [ 15 | { type: ElementRef } 16 | ]; }; 17 | __decorate([ 18 | Output() 19 | ], ClickOutsideDirective.prototype, "clickOutside", void 0); 20 | __decorate([ 21 | HostListener('document:click', ['$event', '$event.target']) 22 | ], ClickOutsideDirective.prototype, "onClick", null); 23 | ClickOutsideDirective = __decorate([ 24 | Directive({ 25 | selector: '[clickOutside]' 26 | }) 27 | ], ClickOutsideDirective); 28 | return ClickOutsideDirective; 29 | }()); 30 | export { ClickOutsideDirective }; 31 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpY2stb3V0c2lkZS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtaW1hZ2UtZ2FsbGVyeS8iLCJzb3VyY2VzIjpbImxpYi9kaXJlY3RpdmVzL2NsaWNrLW91dHNpZGUuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUsxRjtJQUdFLCtCQUFvQixXQUF1QjtRQUF2QixnQkFBVyxHQUFYLFdBQVcsQ0FBWTtRQUZqQyxpQkFBWSxHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDO0lBRWpCLENBQUM7SUFHeEMsdUNBQU8sR0FBZCxVQUFlLE1BQU0sRUFBRSxhQUFhO1FBQ2xDLElBQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUMvRSxJQUFJLENBQUMsZUFBZSxFQUFFO1lBQ3BCLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQ2hDO0lBQ0gsQ0FBQzs7Z0JBUmdDLFVBQVU7O0lBRmpDO1FBQVQsTUFBTSxFQUFFOytEQUFzRDtJQUsvRDtRQURDLFlBQVksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsRUFBRSxlQUFlLENBQUMsQ0FBQzt3REFNM0Q7SUFYVSxxQkFBcUI7UUFIakMsU0FBUyxDQUFDO1lBQ1QsUUFBUSxFQUFFLGdCQUFnQjtTQUMzQixDQUFDO09BQ1cscUJBQXFCLENBWWpDO0lBQUQsNEJBQUM7Q0FBQSxBQVpELElBWUM7U0FaWSxxQkFBcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2NsaWNrT3V0c2lkZV0nXG59KVxuZXhwb3J0IGNsYXNzIENsaWNrT3V0c2lkZURpcmVjdGl2ZSB7XG4gIEBPdXRwdXQoKSBjbGlja091dHNpZGU6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2VsZW1lbnRSZWY6IEVsZW1lbnRSZWYpIHt9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCcsICckZXZlbnQudGFyZ2V0J10pXG4gIHB1YmxpYyBvbkNsaWNrKCRldmVudCwgdGFyZ2V0RWxlbWVudCkge1xuICAgIGNvbnN0IGlzQ2xpY2tlZEluc2lkZSA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jb250YWlucyh0YXJnZXRFbGVtZW50KTtcbiAgICBpZiAoIWlzQ2xpY2tlZEluc2lkZSkge1xuICAgICAgdGhpcy5jbGlja091dHNpZGUuZW1pdCgkZXZlbnQpO1xuICAgIH1cbiAgfVxufSJdfQ== -------------------------------------------------------------------------------- /dist/ngx-image-gallery/esm5/lib/directives/mousewheel.directive.js: -------------------------------------------------------------------------------- 1 | import { __decorate } from "tslib"; 2 | import { Directive, Output, HostListener, EventEmitter } from '@angular/core'; 3 | var MouseWheelDirective = /** @class */ (function () { 4 | function MouseWheelDirective() { 5 | this.mouseWheelUp = new EventEmitter(); 6 | this.mouseWheelDown = new EventEmitter(); 7 | } 8 | MouseWheelDirective.prototype.onMouseWheelChrome = function (event) { 9 | this.mouseWheelFunc(event); 10 | }; 11 | MouseWheelDirective.prototype.onMouseWheelFirefox = function (event) { 12 | this.mouseWheelFunc(event); 13 | }; 14 | MouseWheelDirective.prototype.onMouseWheelIE = function (event) { 15 | this.mouseWheelFunc(event); 16 | }; 17 | MouseWheelDirective.prototype.mouseWheelFunc = function (event) { 18 | var event = window.event || event; // old IE support 19 | var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail))); 20 | if (delta > 0) { 21 | this.mouseWheelUp.emit(event); 22 | } 23 | else if (delta < 0) { 24 | this.mouseWheelDown.emit(event); 25 | } 26 | // for IE 27 | event.returnValue = false; 28 | // for Chrome and Firefox 29 | if (event.preventDefault) { 30 | event.preventDefault(); 31 | } 32 | }; 33 | __decorate([ 34 | Output() 35 | ], MouseWheelDirective.prototype, "mouseWheelUp", void 0); 36 | __decorate([ 37 | Output() 38 | ], MouseWheelDirective.prototype, "mouseWheelDown", void 0); 39 | __decorate([ 40 | HostListener('mousewheel', ['$event']) 41 | ], MouseWheelDirective.prototype, "onMouseWheelChrome", null); 42 | __decorate([ 43 | HostListener('DOMMouseScroll', ['$event']) 44 | ], MouseWheelDirective.prototype, "onMouseWheelFirefox", null); 45 | __decorate([ 46 | HostListener('onmousewheel', ['$event']) 47 | ], MouseWheelDirective.prototype, "onMouseWheelIE", null); 48 | MouseWheelDirective = __decorate([ 49 | Directive({ selector: '[mouseWheel]' }) 50 | ], MouseWheelDirective); 51 | return MouseWheelDirective; 52 | }()); 53 | export { MouseWheelDirective }; 54 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW91c2V3aGVlbC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtaW1hZ2UtZ2FsbGVyeS8iLCJzb3VyY2VzIjpbImxpYi9kaXJlY3RpdmVzL21vdXNld2hlZWwuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRzlFO0lBQUE7UUFDWSxpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDbEMsbUJBQWMsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO0lBNkJoRCxDQUFDO0lBM0J5QyxnREFBa0IsR0FBbEIsVUFBbUIsS0FBVTtRQUNuRSxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFFMkMsaURBQW1CLEdBQW5CLFVBQW9CLEtBQVU7UUFDeEUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBRXlDLDRDQUFjLEdBQWQsVUFBZSxLQUFVO1FBQ2pFLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUVELDRDQUFjLEdBQWQsVUFBZSxLQUFVO1FBQ3ZCLElBQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLENBQUMsaUJBQWlCO1FBQ3BELElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsVUFBVSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzRSxJQUFHLEtBQUssR0FBRyxDQUFDLEVBQUU7WUFDVixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNqQzthQUFNLElBQUcsS0FBSyxHQUFHLENBQUMsRUFBRTtZQUNqQixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNuQztRQUNELFNBQVM7UUFDVCxLQUFLLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztRQUMxQix5QkFBeUI7UUFDekIsSUFBRyxLQUFLLENBQUMsY0FBYyxFQUFFO1lBQ3JCLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztTQUMxQjtJQUNILENBQUM7SUE3QlM7UUFBVCxNQUFNLEVBQUU7NkRBQW1DO0lBQ2xDO1FBQVQsTUFBTSxFQUFFOytEQUFxQztJQUVOO1FBQXZDLFlBQVksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQztpRUFFdEM7SUFFMkM7UUFBM0MsWUFBWSxDQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7a0VBRTFDO0lBRXlDO1FBQXpDLFlBQVksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQzs2REFFeEM7SUFkVSxtQkFBbUI7UUFEL0IsU0FBUyxDQUFDLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxDQUFDO09BQzNCLG1CQUFtQixDQStCL0I7SUFBRCwwQkFBQztDQUFBLEFBL0JELElBK0JDO1NBL0JZLG1CQUFtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgT3V0cHV0LCBIb3N0TGlzdGVuZXIsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbbW91c2VXaGVlbF0nIH0pXG5leHBvcnQgY2xhc3MgTW91c2VXaGVlbERpcmVjdGl2ZSB7XG4gIEBPdXRwdXQoKSBtb3VzZVdoZWVsVXAgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBtb3VzZVdoZWVsRG93biA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBASG9zdExpc3RlbmVyKCdtb3VzZXdoZWVsJywgWyckZXZlbnQnXSkgb25Nb3VzZVdoZWVsQ2hyb21lKGV2ZW50OiBhbnkpIHtcbiAgICB0aGlzLm1vdXNlV2hlZWxGdW5jKGV2ZW50KTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ0RPTU1vdXNlU2Nyb2xsJywgWyckZXZlbnQnXSkgb25Nb3VzZVdoZWVsRmlyZWZveChldmVudDogYW55KSB7XG4gICAgdGhpcy5tb3VzZVdoZWVsRnVuYyhldmVudCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdvbm1vdXNld2hlZWwnLCBbJyRldmVudCddKSBvbk1vdXNlV2hlZWxJRShldmVudDogYW55KSB7XG4gICAgdGhpcy5tb3VzZVdoZWVsRnVuYyhldmVudCk7XG4gIH1cblxuICBtb3VzZVdoZWVsRnVuYyhldmVudDogYW55KSB7XG4gICAgdmFyIGV2ZW50ID0gd2luZG93LmV2ZW50IHx8IGV2ZW50OyAvLyBvbGQgSUUgc3VwcG9ydFxuICAgIHZhciBkZWx0YSA9IE1hdGgubWF4KC0xLCBNYXRoLm1pbigxLCAoZXZlbnQud2hlZWxEZWx0YSB8fCAtZXZlbnQuZGV0YWlsKSkpO1xuICAgIGlmKGRlbHRhID4gMCkge1xuICAgICAgICB0aGlzLm1vdXNlV2hlZWxVcC5lbWl0KGV2ZW50KTtcbiAgICB9IGVsc2UgaWYoZGVsdGEgPCAwKSB7XG4gICAgICAgIHRoaXMubW91c2VXaGVlbERvd24uZW1pdChldmVudCk7XG4gICAgfVxuICAgIC8vIGZvciBJRVxuICAgIGV2ZW50LnJldHVyblZhbHVlID0gZmFsc2U7XG4gICAgLy8gZm9yIENocm9tZSBhbmQgRmlyZWZveFxuICAgIGlmKGV2ZW50LnByZXZlbnREZWZhdWx0KSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG59Il19 -------------------------------------------------------------------------------- /dist/ngx-image-gallery/esm5/lib/index.js: -------------------------------------------------------------------------------- 1 | import { __decorate } from "tslib"; 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { NgxImageGalleryComponent } from './components/ngx-image-gallery/ngx-image-gallery.component'; 5 | import { ClickOutsideDirective } from './directives/click-outside.directive'; 6 | import { MouseWheelDirective } from './directives/mousewheel.directive'; 7 | export * from './components/ngx-image-gallery/ngx-image-gallery.component'; 8 | export * from './directives/click-outside.directive'; 9 | export * from './directives/mousewheel.directive'; 10 | var NgxImageGalleryModule = /** @class */ (function () { 11 | function NgxImageGalleryModule() { 12 | } 13 | NgxImageGalleryModule = __decorate([ 14 | NgModule({ 15 | imports: [ 16 | CommonModule 17 | ], 18 | declarations: [ 19 | NgxImageGalleryComponent, 20 | MouseWheelDirective, 21 | ClickOutsideDirective 22 | ], 23 | exports: [ 24 | NgxImageGalleryComponent, 25 | MouseWheelDirective, 26 | ClickOutsideDirective 27 | ] 28 | }) 29 | ], NgxImageGalleryModule); 30 | return NgxImageGalleryModule; 31 | }()); 32 | export { NgxImageGalleryModule }; 33 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtaW1hZ2UtZ2FsbGVyeS8iLCJzb3VyY2VzIjpbImxpYi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUN2QyxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFFN0MsT0FBTyxFQUFDLHdCQUF3QixFQUFDLE1BQU0sNERBQTRELENBQUM7QUFDcEcsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sc0NBQXNDLENBQUM7QUFDM0UsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sbUNBQW1DLENBQUM7QUFFdEUsY0FBYyw0REFBNEQsQ0FBQztBQUMzRSxjQUFjLHNDQUFzQyxDQUFDO0FBQ3JELGNBQWMsbUNBQW1DLENBQUM7QUFrQmxEO0lBQUE7SUFDQSxDQUFDO0lBRFkscUJBQXFCO1FBZmpDLFFBQVEsQ0FBQztZQUNOLE9BQU8sRUFBRTtnQkFDTCxZQUFZO2FBQ2Y7WUFDRCxZQUFZLEVBQUU7Z0JBQ1Ysd0JBQXdCO2dCQUN4QixtQkFBbUI7Z0JBQ25CLHFCQUFxQjthQUN4QjtZQUNELE9BQU8sRUFBRTtnQkFDTCx3QkFBd0I7Z0JBQ3hCLG1CQUFtQjtnQkFDbkIscUJBQXFCO2FBQ3hCO1NBQ0osQ0FBQztPQUNXLHFCQUFxQixDQUNqQztJQUFELDRCQUFDO0NBQUEsQUFERCxJQUNDO1NBRFkscUJBQXFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtOZ01vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0NvbW1vbk1vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuaW1wb3J0IHtOZ3hJbWFnZUdhbGxlcnlDb21wb25lbnR9IGZyb20gJy4vY29tcG9uZW50cy9uZ3gtaW1hZ2UtZ2FsbGVyeS9uZ3gtaW1hZ2UtZ2FsbGVyeS5jb21wb25lbnQnO1xuaW1wb3J0IHtDbGlja091dHNpZGVEaXJlY3RpdmV9IGZyb20gJy4vZGlyZWN0aXZlcy9jbGljay1vdXRzaWRlLmRpcmVjdGl2ZSc7XG5pbXBvcnQge01vdXNlV2hlZWxEaXJlY3RpdmV9IGZyb20gJy4vZGlyZWN0aXZlcy9tb3VzZXdoZWVsLmRpcmVjdGl2ZSc7XG5cbmV4cG9ydCAqIGZyb20gJy4vY29tcG9uZW50cy9uZ3gtaW1hZ2UtZ2FsbGVyeS9uZ3gtaW1hZ2UtZ2FsbGVyeS5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi9kaXJlY3RpdmVzL2NsaWNrLW91dHNpZGUuZGlyZWN0aXZlJztcbmV4cG9ydCAqIGZyb20gJy4vZGlyZWN0aXZlcy9tb3VzZXdoZWVsLmRpcmVjdGl2ZSc7XG5leHBvcnQgKiBmcm9tICcuL25neC1pbWFnZS1nYWxsZXJ5LmNvbmYnO1xuXG5ATmdNb2R1bGUoe1xuICAgIGltcG9ydHM6IFtcbiAgICAgICAgQ29tbW9uTW9kdWxlXG4gICAgXSxcbiAgICBkZWNsYXJhdGlvbnM6IFtcbiAgICAgICAgTmd4SW1hZ2VHYWxsZXJ5Q29tcG9uZW50LFxuICAgICAgICBNb3VzZVdoZWVsRGlyZWN0aXZlLFxuICAgICAgICBDbGlja091dHNpZGVEaXJlY3RpdmVcbiAgICBdLFxuICAgIGV4cG9ydHM6IFtcbiAgICAgICAgTmd4SW1hZ2VHYWxsZXJ5Q29tcG9uZW50LFxuICAgICAgICBNb3VzZVdoZWVsRGlyZWN0aXZlLFxuICAgICAgICBDbGlja091dHNpZGVEaXJlY3RpdmVcbiAgICBdXG59KVxuZXhwb3J0IGNsYXNzIE5neEltYWdlR2FsbGVyeU1vZHVsZSB7XG59XG4iXX0= -------------------------------------------------------------------------------- /dist/ngx-image-gallery/esm5/lib/ngx-image-gallery.conf.js: -------------------------------------------------------------------------------- 1 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWltYWdlLWdhbGxlcnkuY29uZi5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1pbWFnZS1nYWxsZXJ5LyIsInNvdXJjZXMiOlsibGliL25neC1pbWFnZS1nYWxsZXJ5LmNvbmYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBpbnRlcmZhY2UgR0FMTEVSWV9DT05GIHtcblx0aW1hZ2VCb3JkZXJSYWRpdXM/OiBzdHJpbmc7XG4gICAgaW1hZ2VPZmZzZXQ/OiBzdHJpbmc7XG4gICAgaW1hZ2VQb2ludGVyPyA6Ym9vbGVhbjtcbiAgICBzaG93RGVsZXRlQ29udHJvbD86IGJvb2xlYW47XG5cdHNob3dDbG9zZUNvbnRyb2w/OiBib29sZWFuO1xuXHRzaG93RXh0VXJsQ29udHJvbD86IGJvb2xlYW47XG5cdHNob3dBcnJvd3M/OiBib29sZWFuO1xuXHRzaG93SW1hZ2VUaXRsZT86IGJvb2xlYW47XG5cdHNob3dUaHVtYm5haWxzPzogYm9vbGVhbjtcblx0Y2xvc2VPbkVzYz86IGJvb2xlYW47XG5cdHJlYWN0VG9LZXlib2FyZD86IGJvb2xlYW47XG5cdHJlYWN0VG9Nb3VzZVdoZWVsPzogYm9vbGVhbjtcblx0cmVhY3RUb1JpZ2h0Q2xpY2s/OiBib29sZWFuO1xuXHR0aHVtYm5haWxTaXplPzogbnVtYmVyO1xuXHRiYWNrZHJvcENvbG9yPzogc3RyaW5nO1xuXHRpbmxpbmU/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdBTExFUllfSU1BR0Uge1xuXHRfY2FjaGVkPzogYm9vbGVhbjtcblx0dXJsOiBzdHJpbmc7XG5cdHRodW1ibmFpbFVybD86IHN0cmluZztcblx0YWx0VGV4dD86IHN0cmluZztcblx0dGl0bGU/OiBzdHJpbmc7XG5cdGV4dFVybD86IHN0cmluZztcblx0ZXh0VXJsVGFyZ2V0Pzogc3RyaW5nO1xufSJdfQ== -------------------------------------------------------------------------------- /dist/ngx-image-gallery/esm5/ngx-image-gallery.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generated bundle index. Do not edit. 3 | */ 4 | export * from './public-api'; 5 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWltYWdlLWdhbGxlcnkuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtaW1hZ2UtZ2FsbGVyeS8iLCJzb3VyY2VzIjpbIm5neC1pbWFnZS1nYWxsZXJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vcHVibGljLWFwaSc7XG4iXX0= -------------------------------------------------------------------------------- /dist/ngx-image-gallery/esm5/public-api.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Public API Surface of ngx-image-gallery 3 | */ 4 | export * from './lib/index'; 5 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1pbWFnZS1nYWxsZXJ5LyIsInNvdXJjZXMiOlsicHVibGljLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILGNBQWMsYUFBYSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIFB1YmxpYyBBUEkgU3VyZmFjZSBvZiBuZ3gtaW1hZ2UtZ2FsbGVyeVxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vbGliL2luZGV4JztcbiJdfQ== -------------------------------------------------------------------------------- /dist/ngx-image-gallery/lib/components/ngx-image-gallery/ngx-image-gallery.component.d.ts: -------------------------------------------------------------------------------- 1 | import { OnInit, ElementRef, Renderer2, EventEmitter, OnChanges, SimpleChanges, ChangeDetectorRef } from '@angular/core'; 2 | import { GALLERY_CONF, GALLERY_IMAGE } from '../../ngx-image-gallery.conf'; 3 | import { DomSanitizer } from '@angular/platform-browser'; 4 | export declare class NgxImageGalleryComponent implements OnInit, OnChanges { 5 | sanitizer: DomSanitizer; 6 | private galleryElem; 7 | private renderer; 8 | private cdRef; 9 | opened: boolean; 10 | conf: GALLERY_CONF; 11 | images: GALLERY_IMAGE[]; 12 | onOpen: EventEmitter; 13 | onClose: EventEmitter; 14 | onDelete: EventEmitter; 15 | onImageChange: EventEmitter; 16 | onImageClicked: EventEmitter; 17 | onError: EventEmitter; 18 | thumbnailsElem: ElementRef; 19 | /***************************************************/ 20 | loading: boolean; 21 | activeImageIndex: number; 22 | thumbnailMargin: string; 23 | thumbnailsScrollerLeftMargin: string; 24 | get activeImage(): GALLERY_IMAGE; 25 | get onFirstImage(): boolean; 26 | get onLastImage(): boolean; 27 | get thumbnailsRenderParams(): { 28 | thumbnailsInView: number; 29 | newThumbnailMargin: number; 30 | newThumbnailSize: number; 31 | thumbnailsScrollerLeftMargin: any; 32 | }; 33 | private setGalleryConf; 34 | private loadImage; 35 | private activateImage; 36 | private fitThumbnails; 37 | private scrollThumbnails; 38 | private debouncedPrev; 39 | private debouncedNext; 40 | /***************************************************/ 41 | constructor(sanitizer: DomSanitizer, galleryElem: ElementRef, renderer: Renderer2, cdRef: ChangeDetectorRef); 42 | ngOnInit(): void; 43 | ngOnChanges(changes: SimpleChanges): void; 44 | onKeyboardInput(event: KeyboardEvent): void; 45 | onWindowResize(event: Event): void; 46 | /***************************************************/ 47 | open(index?: number): void; 48 | close(): void; 49 | prev(): void; 50 | next(): void; 51 | setActiveImage(index: number): void; 52 | deleteImage(index: number): void; 53 | mouseWheelUp(): void; 54 | mouseWheelDown(): void; 55 | clickOnImage(index: number): void; 56 | rightClickOnImage(event: Event): boolean; 57 | } 58 | -------------------------------------------------------------------------------- /dist/ngx-image-gallery/lib/directives/click-outside.directive.d.ts: -------------------------------------------------------------------------------- 1 | import { ElementRef, EventEmitter } from '@angular/core'; 2 | export declare class ClickOutsideDirective { 3 | private _elementRef; 4 | clickOutside: EventEmitter; 5 | constructor(_elementRef: ElementRef); 6 | onClick($event: any, targetElement: any): void; 7 | } 8 | -------------------------------------------------------------------------------- /dist/ngx-image-gallery/lib/directives/mousewheel.directive.d.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from '@angular/core'; 2 | export declare class MouseWheelDirective { 3 | mouseWheelUp: EventEmitter; 4 | mouseWheelDown: EventEmitter; 5 | onMouseWheelChrome(event: any): void; 6 | onMouseWheelFirefox(event: any): void; 7 | onMouseWheelIE(event: any): void; 8 | mouseWheelFunc(event: any): void; 9 | } 10 | -------------------------------------------------------------------------------- /dist/ngx-image-gallery/lib/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from './components/ngx-image-gallery/ngx-image-gallery.component'; 2 | export * from './directives/click-outside.directive'; 3 | export * from './directives/mousewheel.directive'; 4 | export * from './ngx-image-gallery.conf'; 5 | export declare class NgxImageGalleryModule { 6 | } 7 | -------------------------------------------------------------------------------- /dist/ngx-image-gallery/lib/ngx-image-gallery.conf.d.ts: -------------------------------------------------------------------------------- 1 | export interface GALLERY_CONF { 2 | imageBorderRadius?: string; 3 | imageOffset?: string; 4 | imagePointer?: boolean; 5 | showDeleteControl?: boolean; 6 | showCloseControl?: boolean; 7 | showExtUrlControl?: boolean; 8 | showArrows?: boolean; 9 | showImageTitle?: boolean; 10 | showThumbnails?: boolean; 11 | closeOnEsc?: boolean; 12 | reactToKeyboard?: boolean; 13 | reactToMouseWheel?: boolean; 14 | reactToRightClick?: boolean; 15 | thumbnailSize?: number; 16 | backdropColor?: string; 17 | inline?: boolean; 18 | } 19 | export interface GALLERY_IMAGE { 20 | _cached?: boolean; 21 | url: string; 22 | thumbnailUrl?: string; 23 | altText?: string; 24 | title?: string; 25 | extUrl?: string; 26 | extUrlTarget?: string; 27 | } 28 | -------------------------------------------------------------------------------- /dist/ngx-image-gallery/ngx-image-gallery.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Generated bundle index. Do not edit. 3 | */ 4 | export * from './public-api'; 5 | -------------------------------------------------------------------------------- /dist/ngx-image-gallery/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@web-aid-kit/ngx-image-gallery", 3 | "version": "v1.0.0-beta", 4 | "peerDependencies": { 5 | "@angular/common": "^9.0.7", 6 | "@angular/core": "^9.0.7", 7 | "hammerjs": "^2.0.8", 8 | "lodash": "^4.17.15", 9 | "tslib": "^1.10.0" 10 | }, 11 | "main": "bundles/ngx-image-gallery.umd.js", 12 | "module": "fesm5/ngx-image-gallery.js", 13 | "es2015": "fesm2015/ngx-image-gallery.js", 14 | "esm5": "esm5/ngx-image-gallery.js", 15 | "esm2015": "esm2015/ngx-image-gallery.js", 16 | "fesm5": "fesm5/ngx-image-gallery.js", 17 | "fesm2015": "fesm2015/ngx-image-gallery.js", 18 | "typings": "ngx-image-gallery.d.ts", 19 | "metadata": "ngx-image-gallery.metadata.json", 20 | "sideEffects": false 21 | } 22 | -------------------------------------------------------------------------------- /dist/ngx-image-gallery/public-api.d.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/index'; 2 | -------------------------------------------------------------------------------- /docs/3rdpartylicenses.txt: -------------------------------------------------------------------------------- 1 | @angular-devkit/build-angular 2 | MIT 3 | The MIT License 4 | 5 | Copyright (c) 2017 Google, Inc. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | 26 | @angular/common 27 | MIT 28 | 29 | @angular/core 30 | MIT 31 | 32 | @angular/forms 33 | MIT 34 | 35 | @angular/platform-browser 36 | MIT 37 | 38 | core-js 39 | MIT 40 | Copyright (c) 2014-2020 Denis Pushkarev 41 | 42 | Permission is hereby granted, free of charge, to any person obtaining a copy 43 | of this software and associated documentation files (the "Software"), to deal 44 | in the Software without restriction, including without limitation the rights 45 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 46 | copies of the Software, and to permit persons to whom the Software is 47 | furnished to do so, subject to the following conditions: 48 | 49 | The above copyright notice and this permission notice shall be included in 50 | all copies or substantial portions of the Software. 51 | 52 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 53 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 54 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 55 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 56 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 57 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 58 | THE SOFTWARE. 59 | 60 | 61 | hammerjs 62 | MIT 63 | The MIT License (MIT) 64 | 65 | Copyright (C) 2011-2014 by Jorik Tangelder (Eight Media) 66 | 67 | Permission is hereby granted, free of charge, to any person obtaining a copy 68 | of this software and associated documentation files (the "Software"), to deal 69 | in the Software without restriction, including without limitation the rights 70 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 71 | copies of the Software, and to permit persons to whom the Software is 72 | furnished to do so, subject to the following conditions: 73 | 74 | The above copyright notice and this permission notice shall be included in 75 | all copies or substantial portions of the Software. 76 | 77 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 78 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 79 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 80 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 81 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 82 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 83 | THE SOFTWARE. 84 | 85 | 86 | lodash 87 | MIT 88 | Copyright OpenJS Foundation and other contributors 89 | 90 | Based on Underscore.js, copyright Jeremy Ashkenas, 91 | DocumentCloud and Investigative Reporters & Editors 92 | 93 | This software consists of voluntary contributions made by many 94 | individuals. For exact contribution history, see the revision history 95 | available at https://github.com/lodash/lodash 96 | 97 | The following license applies to all parts of this software except as 98 | documented below: 99 | 100 | ==== 101 | 102 | Permission is hereby granted, free of charge, to any person obtaining 103 | a copy of this software and associated documentation files (the 104 | "Software"), to deal in the Software without restriction, including 105 | without limitation the rights to use, copy, modify, merge, publish, 106 | distribute, sublicense, and/or sell copies of the Software, and to 107 | permit persons to whom the Software is furnished to do so, subject to 108 | the following conditions: 109 | 110 | The above copyright notice and this permission notice shall be 111 | included in all copies or substantial portions of the Software. 112 | 113 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 114 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 115 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 116 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 117 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 118 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 119 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 120 | 121 | ==== 122 | 123 | Copyright and related rights for sample code are waived via CC0. Sample 124 | code is defined as all source code displayed within the prose of the 125 | documentation. 126 | 127 | CC0: http://creativecommons.org/publicdomain/zero/1.0/ 128 | 129 | ==== 130 | 131 | Files located in the node_modules and vendor directories are externally 132 | maintained libraries used by this software which have their own 133 | licenses; we recommend you read them, as their terms may differ from the 134 | terms above. 135 | 136 | 137 | ngx-image-gallery 138 | 139 | regenerator-runtime 140 | MIT 141 | MIT License 142 | 143 | Copyright (c) 2014-present, Facebook, Inc. 144 | 145 | Permission is hereby granted, free of charge, to any person obtaining a copy 146 | of this software and associated documentation files (the "Software"), to deal 147 | in the Software without restriction, including without limitation the rights 148 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 149 | copies of the Software, and to permit persons to whom the Software is 150 | furnished to do so, subject to the following conditions: 151 | 152 | The above copyright notice and this permission notice shall be included in all 153 | copies or substantial portions of the Software. 154 | 155 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 156 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 157 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 158 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 159 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 160 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 161 | SOFTWARE. 162 | 163 | 164 | rxjs 165 | Apache-2.0 166 | Apache License 167 | Version 2.0, January 2004 168 | http://www.apache.org/licenses/ 169 | 170 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 171 | 172 | 1. Definitions. 173 | 174 | "License" shall mean the terms and conditions for use, reproduction, 175 | and distribution as defined by Sections 1 through 9 of this document. 176 | 177 | "Licensor" shall mean the copyright owner or entity authorized by 178 | the copyright owner that is granting the License. 179 | 180 | "Legal Entity" shall mean the union of the acting entity and all 181 | other entities that control, are controlled by, or are under common 182 | control with that entity. For the purposes of this definition, 183 | "control" means (i) the power, direct or indirect, to cause the 184 | direction or management of such entity, whether by contract or 185 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 186 | outstanding shares, or (iii) beneficial ownership of such entity. 187 | 188 | "You" (or "Your") shall mean an individual or Legal Entity 189 | exercising permissions granted by this License. 190 | 191 | "Source" form shall mean the preferred form for making modifications, 192 | including but not limited to software source code, documentation 193 | source, and configuration files. 194 | 195 | "Object" form shall mean any form resulting from mechanical 196 | transformation or translation of a Source form, including but 197 | not limited to compiled object code, generated documentation, 198 | and conversions to other media types. 199 | 200 | "Work" shall mean the work of authorship, whether in Source or 201 | Object form, made available under the License, as indicated by a 202 | copyright notice that is included in or attached to the work 203 | (an example is provided in the Appendix below). 204 | 205 | "Derivative Works" shall mean any work, whether in Source or Object 206 | form, that is based on (or derived from) the Work and for which the 207 | editorial revisions, annotations, elaborations, or other modifications 208 | represent, as a whole, an original work of authorship. For the purposes 209 | of this License, Derivative Works shall not include works that remain 210 | separable from, or merely link (or bind by name) to the interfaces of, 211 | the Work and Derivative Works thereof. 212 | 213 | "Contribution" shall mean any work of authorship, including 214 | the original version of the Work and any modifications or additions 215 | to that Work or Derivative Works thereof, that is intentionally 216 | submitted to Licensor for inclusion in the Work by the copyright owner 217 | or by an individual or Legal Entity authorized to submit on behalf of 218 | the copyright owner. For the purposes of this definition, "submitted" 219 | means any form of electronic, verbal, or written communication sent 220 | to the Licensor or its representatives, including but not limited to 221 | communication on electronic mailing lists, source code control systems, 222 | and issue tracking systems that are managed by, or on behalf of, the 223 | Licensor for the purpose of discussing and improving the Work, but 224 | excluding communication that is conspicuously marked or otherwise 225 | designated in writing by the copyright owner as "Not a Contribution." 226 | 227 | "Contributor" shall mean Licensor and any individual or Legal Entity 228 | on behalf of whom a Contribution has been received by Licensor and 229 | subsequently incorporated within the Work. 230 | 231 | 2. Grant of Copyright License. Subject to the terms and conditions of 232 | this License, each Contributor hereby grants to You a perpetual, 233 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 234 | copyright license to reproduce, prepare Derivative Works of, 235 | publicly display, publicly perform, sublicense, and distribute the 236 | Work and such Derivative Works in Source or Object form. 237 | 238 | 3. Grant of Patent License. Subject to the terms and conditions of 239 | this License, each Contributor hereby grants to You a perpetual, 240 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 241 | (except as stated in this section) patent license to make, have made, 242 | use, offer to sell, sell, import, and otherwise transfer the Work, 243 | where such license applies only to those patent claims licensable 244 | by such Contributor that are necessarily infringed by their 245 | Contribution(s) alone or by combination of their Contribution(s) 246 | with the Work to which such Contribution(s) was submitted. If You 247 | institute patent litigation against any entity (including a 248 | cross-claim or counterclaim in a lawsuit) alleging that the Work 249 | or a Contribution incorporated within the Work constitutes direct 250 | or contributory patent infringement, then any patent licenses 251 | granted to You under this License for that Work shall terminate 252 | as of the date such litigation is filed. 253 | 254 | 4. Redistribution. You may reproduce and distribute copies of the 255 | Work or Derivative Works thereof in any medium, with or without 256 | modifications, and in Source or Object form, provided that You 257 | meet the following conditions: 258 | 259 | (a) You must give any other recipients of the Work or 260 | Derivative Works a copy of this License; and 261 | 262 | (b) You must cause any modified files to carry prominent notices 263 | stating that You changed the files; and 264 | 265 | (c) You must retain, in the Source form of any Derivative Works 266 | that You distribute, all copyright, patent, trademark, and 267 | attribution notices from the Source form of the Work, 268 | excluding those notices that do not pertain to any part of 269 | the Derivative Works; and 270 | 271 | (d) If the Work includes a "NOTICE" text file as part of its 272 | distribution, then any Derivative Works that You distribute must 273 | include a readable copy of the attribution notices contained 274 | within such NOTICE file, excluding those notices that do not 275 | pertain to any part of the Derivative Works, in at least one 276 | of the following places: within a NOTICE text file distributed 277 | as part of the Derivative Works; within the Source form or 278 | documentation, if provided along with the Derivative Works; or, 279 | within a display generated by the Derivative Works, if and 280 | wherever such third-party notices normally appear. The contents 281 | of the NOTICE file are for informational purposes only and 282 | do not modify the License. You may add Your own attribution 283 | notices within Derivative Works that You distribute, alongside 284 | or as an addendum to the NOTICE text from the Work, provided 285 | that such additional attribution notices cannot be construed 286 | as modifying the License. 287 | 288 | You may add Your own copyright statement to Your modifications and 289 | may provide additional or different license terms and conditions 290 | for use, reproduction, or distribution of Your modifications, or 291 | for any such Derivative Works as a whole, provided Your use, 292 | reproduction, and distribution of the Work otherwise complies with 293 | the conditions stated in this License. 294 | 295 | 5. Submission of Contributions. Unless You explicitly state otherwise, 296 | any Contribution intentionally submitted for inclusion in the Work 297 | by You to the Licensor shall be under the terms and conditions of 298 | this License, without any additional terms or conditions. 299 | Notwithstanding the above, nothing herein shall supersede or modify 300 | the terms of any separate license agreement you may have executed 301 | with Licensor regarding such Contributions. 302 | 303 | 6. Trademarks. This License does not grant permission to use the trade 304 | names, trademarks, service marks, or product names of the Licensor, 305 | except as required for reasonable and customary use in describing the 306 | origin of the Work and reproducing the content of the NOTICE file. 307 | 308 | 7. Disclaimer of Warranty. Unless required by applicable law or 309 | agreed to in writing, Licensor provides the Work (and each 310 | Contributor provides its Contributions) on an "AS IS" BASIS, 311 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 312 | implied, including, without limitation, any warranties or conditions 313 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 314 | PARTICULAR PURPOSE. You are solely responsible for determining the 315 | appropriateness of using or redistributing the Work and assume any 316 | risks associated with Your exercise of permissions under this License. 317 | 318 | 8. Limitation of Liability. In no event and under no legal theory, 319 | whether in tort (including negligence), contract, or otherwise, 320 | unless required by applicable law (such as deliberate and grossly 321 | negligent acts) or agreed to in writing, shall any Contributor be 322 | liable to You for damages, including any direct, indirect, special, 323 | incidental, or consequential damages of any character arising as a 324 | result of this License or out of the use or inability to use the 325 | Work (including but not limited to damages for loss of goodwill, 326 | work stoppage, computer failure or malfunction, or any and all 327 | other commercial damages or losses), even if such Contributor 328 | has been advised of the possibility of such damages. 329 | 330 | 9. Accepting Warranty or Additional Liability. While redistributing 331 | the Work or Derivative Works thereof, You may choose to offer, 332 | and charge a fee for, acceptance of support, warranty, indemnity, 333 | or other liability obligations and/or rights consistent with this 334 | License. However, in accepting such obligations, You may act only 335 | on Your own behalf and on Your sole responsibility, not on behalf 336 | of any other Contributor, and only if You agree to indemnify, 337 | defend, and hold each Contributor harmless for any liability 338 | incurred by, or claims asserted against, such Contributor by reason 339 | of your accepting any such warranty or additional liability. 340 | 341 | END OF TERMS AND CONDITIONS 342 | 343 | APPENDIX: How to apply the Apache License to your work. 344 | 345 | To apply the Apache License to your work, attach the following 346 | boilerplate notice, with the fields enclosed by brackets "[]" 347 | replaced with your own identifying information. (Don't include 348 | the brackets!) The text should be enclosed in the appropriate 349 | comment syntax for the file format. We also recommend that a 350 | file or class name and description of purpose be included on the 351 | same "printed page" as the copyright notice for easier 352 | identification within third-party archives. 353 | 354 | Copyright (c) 2015-2018 Google, Inc., Netflix, Inc., Microsoft Corp. and contributors 355 | 356 | Licensed under the Apache License, Version 2.0 (the "License"); 357 | you may not use this file except in compliance with the License. 358 | You may obtain a copy of the License at 359 | 360 | http://www.apache.org/licenses/LICENSE-2.0 361 | 362 | Unless required by applicable law or agreed to in writing, software 363 | distributed under the License is distributed on an "AS IS" BASIS, 364 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 365 | See the License for the specific language governing permissions and 366 | limitations under the License. 367 | 368 | 369 | 370 | webpack 371 | MIT 372 | Copyright JS Foundation and other contributors 373 | 374 | Permission is hereby granted, free of charge, to any person obtaining 375 | a copy of this software and associated documentation files (the 376 | 'Software'), to deal in the Software without restriction, including 377 | without limitation the rights to use, copy, modify, merge, publish, 378 | distribute, sublicense, and/or sell copies of the Software, and to 379 | permit persons to whom the Software is furnished to do so, subject to 380 | the following conditions: 381 | 382 | The above copyright notice and this permission notice shall be 383 | included in all copies or substantial portions of the Software. 384 | 385 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 386 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 387 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 388 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 389 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 390 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 391 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 392 | 393 | 394 | zone.js 395 | MIT 396 | The MIT License 397 | 398 | Copyright (c) 2010-2020 Google LLC. http://angular.io/license 399 | 400 | Permission is hereby granted, free of charge, to any person obtaining a copy 401 | of this software and associated documentation files (the "Software"), to deal 402 | in the Software without restriction, including without limitation the rights 403 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 404 | copies of the Software, and to permit persons to whom the Software is 405 | furnished to do so, subject to the following conditions: 406 | 407 | The above copyright notice and this permission notice shall be included in 408 | all copies or substantial portions of the Software. 409 | 410 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 411 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 412 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 413 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 414 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 415 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 416 | THE SOFTWARE. 417 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/web-aid-kit/ngx-image-gallery/2a3108a834037fb9377aa1cc0f7834679fc2bfbd/docs/favicon.ico -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Preview 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/runtime-es2015.0811dcefd377500b5b1a.js: -------------------------------------------------------------------------------- 1 | !function(e){function r(r){for(var n,l,f=r[0],i=r[1],p=r[2],c=0,s=[];c 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /preview/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 31 | } 32 | }; -------------------------------------------------------------------------------- /preview/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('preview app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /preview/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo(): Promise { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText(): Promise { 9 | return element(by.css('app-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /preview/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /preview/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/preview'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /preview/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "preview", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "start": "ng serve", 6 | "build": "ng build --prod" 7 | }, 8 | "private": true, 9 | "dependencies": { 10 | "@angular/animations": "~9.0.7", 11 | "@angular/common": "~9.0.7", 12 | "@angular/compiler": "~9.0.7", 13 | "@angular/core": "~9.0.7", 14 | "@angular/forms": "~9.0.7", 15 | "@angular/platform-browser": "~9.0.7", 16 | "@angular/platform-browser-dynamic": "~9.0.7", 17 | "@angular/router": "~9.0.7", 18 | "hammerjs": "^2.0.8", 19 | "lodash": "^4.17.15", 20 | "ngx-image-gallery": "^2.0.3", 21 | "rxjs": "~6.5.4", 22 | "tslib": "^1.10.0", 23 | "zone.js": "~0.10.2" 24 | }, 25 | "devDependencies": { 26 | "@angular-devkit/build-angular": "~0.900.7", 27 | "@angular/cli": "~9.0.7", 28 | "@angular/compiler-cli": "~9.0.7", 29 | "@angular/language-service": "~9.0.7", 30 | "@types/node": "^12.11.1", 31 | "@types/jasmine": "~3.5.0", 32 | "@types/jasminewd2": "~2.0.3", 33 | "codelyzer": "^5.1.2", 34 | "jasmine-core": "~3.5.0", 35 | "jasmine-spec-reporter": "~4.2.1", 36 | "karma": "~4.3.0", 37 | "karma-chrome-launcher": "~3.1.0", 38 | "karma-coverage-istanbul-reporter": "~2.1.0", 39 | "karma-jasmine": "~2.0.1", 40 | "karma-jasmine-html-reporter": "^1.4.2", 41 | "protractor": "~5.4.3", 42 | "ts-node": "~8.3.0", 43 | "tslint": "~5.18.0", 44 | "typescript": "~3.7.5" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /preview/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |

2 | ngx-image-gallery 3 |

4 | 5 |
6 | 7 |
8 | 9 | 12 |
13 | 14 | 15 |
16 | 17 | 20 |
21 | 22 | 23 |
24 | 25 | 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 |
115 | 116 | 117 |
118 | 119 | 120 |
121 | 122 | 123 |
124 |
125 | 126 | 127 |
128 | 129 | 130 |
131 | 132 | 133 |
134 |
135 | 136 | 137 |
138 | 139 | 140 |
141 | 142 | 143 |
144 |
145 | 146 | 147 |
148 | 149 |
150 |
151 | 152 | 153 |
154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /preview/src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | :host{ 2 | display: block; 3 | position: relative; 4 | padding: 30px; 5 | 6 | >h1{ 7 | text-align: center; 8 | } 9 | 10 | >.form{ 11 | input, 12 | select{ 13 | border-radius: 0px !important; 14 | } 15 | 16 | >.field{ 17 | >.inline{ 18 | display: flex; 19 | justify-content: flex-start; 20 | align-items: center; 21 | 22 | >label{ 23 | margin-right: 20px; 24 | cursor: pointer; 25 | } 26 | } 27 | } 28 | 29 | >.button-container{ 30 | margin-top: 20px; 31 | 32 | >.button{ 33 | border-radius: 0px; 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /preview/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewChild } from '@angular/core'; 2 | import { NgxImageGalleryComponent, GALLERY_IMAGE, GALLERY_CONF } from 'ngx-image-gallery'; 3 | import { NgForm } from "@angular/forms"; 4 | import _ from 'lodash'; 5 | 6 | @Component({ 7 | selector: 'app-root', 8 | templateUrl: './app.component.html', 9 | styleUrls: ['./app.component.scss'] 10 | }) 11 | export class AppComponent implements OnInit { 12 | @ViewChild(NgxImageGalleryComponent) ngxImageGallery: NgxImageGalleryComponent; 13 | 14 | images: GALLERY_IMAGE[] = [ 15 | { 16 | url: "https://images.unsplash.com/photo-1507097489474-c9212a8f8597?fit=crop&w=1351&q=80", 17 | altText: 'Is education residence conveying so so.', 18 | extUrl: 'https://unsplash.com/photos/WHPsxhB4mWQ', 19 | title: 'Is education residence conveying so so.', 20 | thumbnailUrl: "https://images.unsplash.com/photo-1507097489474-c9212a8f8597?fit=crop&w=60" 21 | }, 22 | { 23 | url: "https://images.unsplash.com/photo-1512722328319-51c3d027c228?fit=crop&w=634&q=80", 24 | altText: 'He my polite be object oh change.', 25 | title: 'He my polite be object oh change.', 26 | thumbnailUrl: "https://images.unsplash.com/photo-1512722328319-51c3d027c228?fit=crop&w=60" 27 | }, 28 | { 29 | url: "https://images.unsplash.com/photo-1585054285389-200faa8a353c?fit=crop&w=1350&q=80", 30 | altText: 'Separate families my on drawings do oh offended strictly elegance.', 31 | thumbnailUrl: "https://images.unsplash.com/photo-1585054285389-200faa8a353c?fit=crop&w=60" 32 | }, 33 | { 34 | url: "https://images.unsplash.com/photo-1475078891680-4a52da36b99f?fit=crop&w=626&q=80", 35 | extUrl: 'https://unsplash.com/photos/2aomZq8JUvA', 36 | extUrlTarget: '_self', 37 | title: 'Add you viewing ten equally believe put.', 38 | thumbnailUrl: "https://images.unsplash.com/photo-1475078891680-4a52da36b99f?fit=crop&w=60" 39 | }, 40 | { 41 | url: "https://images.unsplash.com/photo-1572933014070-3aec28ebba4d?fit=crop&w=1194&q=80", 42 | altText: 'Now seven world think timed while her.', 43 | extUrl: 'https://unsplash.com/photos/QPqD-w28ADc', 44 | title: 'Now seven world think timed while her.', 45 | thumbnailUrl: "https://images.unsplash.com/photo-1572933014070-3aec28ebba4d?fit=crop&w=60" 46 | }, 47 | { 48 | url: "https://images.unsplash.com/photo-1484519213701-f60f23ec40c6?fit=crop&w=1350&q=80", 49 | altText: 'An admiration at he discovered difficulty continuing.', 50 | extUrl: 'https://unsplash.com/photos/1fuYkTG5DBc', 51 | title: 'An admiration at he discovered difficulty continuing.', 52 | thumbnailUrl: "https://images.unsplash.com/photo-1484519213701-f60f23ec40c6?fit=crop&w=60" 53 | }, 54 | { 55 | url: "https://images.unsplash.com/photo-1498569086936-33ccd92e4789?fit=crop&w=700&q=80", 56 | thumbnailUrl: "https://images.unsplash.com/photo-1498569086936-33ccd92e4789?fit=crop&w=60" 57 | }, 58 | { 59 | url: "https://images.unsplash.com/photo-1522968280648-16e1237ecf46?fit=crop&w=634&q=80", 60 | altText: '', 61 | extUrl: 'https://unsplash.com/photos/BEsp0GzUCmQ', 62 | title: 'Spoil large oh he rooms on since an. Am up unwilling eagerness perceived incommode. Are not windows set luckily musical hundred can. Collecting if sympathize middletons be of of reasonably.', 63 | thumbnailUrl: "https://images.unsplash.com/photo-1522968280648-16e1237ecf46?fit=crop&w=60" 64 | }, 65 | { 66 | url: "https://images.unsplash.com/photo-1546373727-f803b7298d14?fit=crop&w=1491&q=80", 67 | altText: 'Agreed joy vanity regret met may ladies oppose who. ', 68 | title: 'Agreed joy vanity regret met may ladies oppose who. ', 69 | thumbnailUrl: "https://images.unsplash.com/photo-1546373727-f803b7298d14?fit=crop&w=60" 70 | }, 71 | { 72 | url: "https://images.unsplash.com/photo-1584598147703-b4769ffb2c89?fit=crop&w=1350&q=80", 73 | altText: 'Mile fail as left as hard eyes. ', 74 | extUrl: 'https://unsplash.com/photos/dr18lpelFRQ', 75 | title: 'Mile fail as left as hard eyes. ', 76 | thumbnailUrl: "https://images.unsplash.com/photo-1584598147703-b4769ffb2c89?fit=crop&w=60" 77 | }, 78 | { 79 | url: "https://images.unsplash.com/photo-1481800997946-d2a9f2c82683?fit=crop&w=1316&q=80", 80 | altText: 'Meet made call in mean four year it to.', 81 | title: 'Meet made call in mean four year it to.', 82 | thumbnailUrl: "https://images.unsplash.com/photo-1481800997946-d2a9f2c82683?fit=crop&w=60" 83 | }, 84 | { 85 | url: "https://images.unsplash.com/photo-1487603527224-a650979f288e?fit=crop&w=1350&q=80", 86 | altText: 'Prospect so branched wondered sensible of up.', 87 | extUrl: 'https://unsplash.com/photos/oSZzkAqIRIM', 88 | title: 'Prospect so branched wondered sensible of up.', 89 | thumbnailUrl: "https://images.unsplash.com/photo-1487603527224-a650979f288e?fit=crop&w=60" 90 | }, 91 | ]; 92 | 93 | conf: GALLERY_CONF = { 94 | imageBorderRadius: '3px', 95 | imageOffset: '20px', 96 | showDeleteControl: true, 97 | showCloseControl: true, 98 | showExtUrlControl: true, 99 | showImageTitle: true, 100 | showThumbnails: true, 101 | closeOnEsc: true, 102 | reactToKeyboard: true, 103 | reactToMouseWheel: true, 104 | reactToRightClick: false, 105 | thumbnailSize: 30, 106 | backdropColor: 'rgba(13,13,14,0.85)', 107 | inline: false, 108 | showArrows: true, 109 | imagePointer: true 110 | }; 111 | 112 | range = _.range; 113 | 114 | constructor(){} 115 | 116 | ngOnInit() {} 117 | 118 | // open gallery 119 | openGallery(form: NgForm) { 120 | this.conf = form.value; 121 | this.ngxImageGallery.open(0); 122 | } 123 | 124 | // callback on gallery opened 125 | galleryOpened(index) { 126 | console.info('Gallery opened at index ', index); 127 | } 128 | 129 | // callback on gallery closed 130 | galleryClosed() { 131 | console.info('Gallery closed.'); 132 | } 133 | 134 | // callback on gallery image changed 135 | galleryImageChanged(index) { 136 | console.info('Gallery image changed to index ', index); 137 | } 138 | 139 | // callback on gallery image clicked 140 | galleryImageClicked(index) { 141 | console.info('Gallery image clicked with index ', index); 142 | } 143 | 144 | // callback on user clicked delete button 145 | deleteImage(index) { 146 | console.info('Delete image at index ', index); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /preview/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 4 | import { CommonModule } from '@angular/common'; 5 | import { HttpClientModule } from '@angular/common/http'; 6 | import { NgxImageGalleryModule } from 'ngx-image-gallery'; 7 | 8 | // hammerjs 9 | import 'hammerjs'; 10 | 11 | // entry component 12 | import { AppComponent } from './app.component'; 13 | 14 | @NgModule({ 15 | declarations: [ 16 | AppComponent, 17 | ], 18 | imports: [ 19 | BrowserModule, 20 | FormsModule, 21 | ReactiveFormsModule, 22 | CommonModule, 23 | HttpClientModule, 24 | NgxImageGalleryModule, 25 | ], 26 | providers: [], 27 | bootstrap: [AppComponent] 28 | }) 29 | export class AppModule { } 30 | -------------------------------------------------------------------------------- /preview/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/web-aid-kit/ngx-image-gallery/2a3108a834037fb9377aa1cc0f7834679fc2bfbd/preview/src/assets/.gitkeep -------------------------------------------------------------------------------- /preview/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /preview/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /preview/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/web-aid-kit/ngx-image-gallery/2a3108a834037fb9377aa1cc0f7834679fc2bfbd/preview/src/favicon.ico -------------------------------------------------------------------------------- /preview/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Preview 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /preview/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /preview/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | -------------------------------------------------------------------------------- /preview/src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /preview/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: { 11 | context(path: string, deep?: boolean, filter?: RegExp): { 12 | keys(): string[]; 13 | (id: string): T; 14 | }; 15 | }; 16 | 17 | // First, initialize the Angular testing environment. 18 | getTestBed().initTestEnvironment( 19 | BrowserDynamicTestingModule, 20 | platformBrowserDynamicTesting() 21 | ); 22 | // Then we find all the tests. 23 | const context = require.context('./', true, /\.spec\.ts$/); 24 | // And load the modules. 25 | context.keys().map(context); 26 | -------------------------------------------------------------------------------- /preview/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "baseUrl": "./", 6 | "module": "es2015", 7 | "types": [] 8 | }, 9 | "exclude": [ 10 | "test.ts", 11 | "**/*.spec.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /preview/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "target": "es5", 8 | "types": [ 9 | "jasmine", 10 | "node" 11 | ] 12 | }, 13 | "files": [ 14 | "test.ts" 15 | ], 16 | "include": [ 17 | "**/*.spec.ts", 18 | "**/*.d.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /preview/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /preview/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "src/main.ts", 9 | "src/polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /preview/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "lib": [ 15 | "es2018", 16 | "dom" 17 | ] 18 | }, 19 | "angularCompilerOptions": { 20 | "fullTemplateTypeCheck": true, 21 | "strictInjectionParameters": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /preview/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /preview/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rules": { 4 | "array-type": false, 5 | "arrow-parens": false, 6 | "deprecation": { 7 | "severity": "warning" 8 | }, 9 | "component-class-suffix": true, 10 | "contextual-lifecycle": true, 11 | "directive-class-suffix": true, 12 | "directive-selector": [ 13 | true, 14 | "attribute", 15 | "app", 16 | "camelCase" 17 | ], 18 | "component-selector": [ 19 | true, 20 | "element", 21 | "app", 22 | "kebab-case" 23 | ], 24 | "import-blacklist": [ 25 | true, 26 | "rxjs/Rx" 27 | ], 28 | "interface-name": false, 29 | "max-classes-per-file": false, 30 | "max-line-length": [ 31 | true, 32 | 140 33 | ], 34 | "member-access": false, 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-consecutive-blank-lines": false, 47 | "no-console": [ 48 | true, 49 | "debug", 50 | "info", 51 | "time", 52 | "timeEnd", 53 | "trace" 54 | ], 55 | "no-empty": false, 56 | "no-inferrable-types": [ 57 | true, 58 | "ignore-params" 59 | ], 60 | "no-non-null-assertion": true, 61 | "no-redundant-jsdoc": true, 62 | "no-switch-case-fall-through": true, 63 | "no-var-requires": false, 64 | "object-literal-key-quotes": [ 65 | true, 66 | "as-needed" 67 | ], 68 | "object-literal-sort-keys": false, 69 | "ordered-imports": false, 70 | "quotemark": [ 71 | true, 72 | "single" 73 | ], 74 | "trailing-comma": false, 75 | "no-conflicting-lifecycle": true, 76 | "no-host-metadata-property": true, 77 | "no-input-rename": true, 78 | "no-inputs-metadata-property": true, 79 | "no-output-native": true, 80 | "no-output-on-prefix": true, 81 | "no-output-rename": true, 82 | "no-outputs-metadata-property": true, 83 | "template-banana-in-box": true, 84 | "template-no-negated-async": true, 85 | "use-lifecycle-interface": true, 86 | "use-pipe-transform-interface": true 87 | }, 88 | "rulesDirectory": [ 89 | "codelyzer" 90 | ] 91 | } -------------------------------------------------------------------------------- /src/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /src/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "ngx-image-gallery": { 7 | "projectType": "library", 8 | "root": "projects/ngx-image-gallery", 9 | "sourceRoot": "projects/ngx-image-gallery/src", 10 | "prefix": "lib", 11 | "architect": { 12 | "build": { 13 | "builder": "@angular-devkit/build-ng-packagr:build", 14 | "options": { 15 | "tsConfig": "projects/ngx-image-gallery/tsconfig.lib.json", 16 | "project": "projects/ngx-image-gallery/ng-package.json" 17 | }, 18 | "configurations": { 19 | "production": { 20 | "tsConfig": "projects/ngx-image-gallery/tsconfig.lib.prod.json" 21 | } 22 | } 23 | }, 24 | "test": { 25 | "builder": "@angular-devkit/build-angular:karma", 26 | "options": { 27 | "main": "projects/ngx-image-gallery/src/test.ts", 28 | "tsConfig": "projects/ngx-image-gallery/tsconfig.spec.json", 29 | "karmaConfig": "projects/ngx-image-gallery/karma.conf.js" 30 | } 31 | }, 32 | "lint": { 33 | "builder": "@angular-devkit/build-angular:tslint", 34 | "options": { 35 | "tsConfig": [ 36 | "projects/ngx-image-gallery/tsconfig.lib.json", 37 | "projects/ngx-image-gallery/tsconfig.spec.json" 38 | ], 39 | "exclude": [ 40 | "**/node_modules/**" 41 | ] 42 | } 43 | } 44 | } 45 | }}, 46 | "defaultProject": "ngx-image-gallery" 47 | } 48 | -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "@web-aid-kit/ngx-image-gallery", 4 | "version": "0.0.0", 5 | "scripts": { 6 | "build": "ng build ngx-image-gallery --prod", 7 | "publish": "cd ../dist/ngx-image-gallery && npm publish" 8 | }, 9 | "dependencies": { 10 | "@angular/animations": "~9.0.7", 11 | "@angular/common": "~9.0.7", 12 | "@angular/compiler": "~9.0.7", 13 | "@angular/core": "~9.0.7", 14 | "@angular/forms": "~9.0.7", 15 | "@angular/platform-browser": "~9.0.7", 16 | "@angular/platform-browser-dynamic": "~9.0.7", 17 | "@angular/router": "~9.0.7", 18 | "hammerjs": "^2.0.8", 19 | "lodash": "^4.17.15", 20 | "rxjs": "~6.5.4", 21 | "tslib": "^1.10.0", 22 | "zone.js": "~0.10.2" 23 | }, 24 | "devDependencies": { 25 | "@angular-devkit/build-angular": "~0.900.7", 26 | "@angular-devkit/build-ng-packagr": "~0.900.7", 27 | "@angular/cli": "~9.0.7", 28 | "@angular/compiler-cli": "~9.0.7", 29 | "@angular/language-service": "~9.0.7", 30 | "@types/node": "^12.11.1", 31 | "@types/jasmine": "~3.5.0", 32 | "@types/jasminewd2": "~2.0.3", 33 | "codelyzer": "^5.1.2", 34 | "jasmine-core": "~3.5.0", 35 | "jasmine-spec-reporter": "~4.2.1", 36 | "karma": "~4.3.0", 37 | "karma-chrome-launcher": "~3.1.0", 38 | "karma-coverage-istanbul-reporter": "~2.1.0", 39 | "karma-jasmine": "~2.0.1", 40 | "karma-jasmine-html-reporter": "^1.4.2", 41 | "ng-packagr": "^9.0.0", 42 | "protractor": "~5.4.3", 43 | "ts-node": "~8.3.0", 44 | "tslint": "~5.18.0", 45 | "typescript": "~3.7.5" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/README.md: -------------------------------------------------------------------------------- 1 | # Need maintainers 2 | Due to my hectic schedule, it is getting hard to maintain this repository. If anybody is interested to work on this project, please give a pull request to fix some critical issues and enhancements. 3 | 4 | --- 5 | 6 | # ngx-image-gallery 7 | Probably the best Angular 4+ modal and inline image gallery. Angular upgrade for ng-image-gallery. 8 | 9 | [![preview](https://i.imgur.com/1gGxBLd.jpg)](https://thatisuday.github.io) 10 | 11 | [![npm](https://img.shields.io/npm/dt/ngx-image-gallery.svg?style=flat-square)](https://www.npmjs.com/package/ngx-image-gallery) 12 | [![npm](https://img.shields.io/npm/v/ngx-image-gallery.svg?style=flat-square)](https://www.npmjs.com/package/ngx-image-gallery) 13 | [![David](https://img.shields.io/david/thatisuday/ngx-image-gallery.svg?style=flat-square)](https://www.npmjs.com/package/ngx-image-gallery) 14 | [![preview](https://img.shields.io/badge/preview-click_here-green.svg?style=flat-square)](https://thatisuday.github.io/ngx-image-gallery) 15 | 16 | ## Prerequisites 17 | 18 | - Hammerjs (required for swipe) 19 | ``` 20 | npm i -S hammerjs lodash 21 | ``` 22 | 23 | Then import hammerjs into your project (tip: in you main.ts file), e.g: 24 | ``` 25 | import 'hammerjs'; 26 | import { enableProdMode } from '@angular/core'; 27 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 28 | 29 | import { AppModule } from './app/app.module'; 30 | import { environment } from './environments/environment'; 31 | 32 | if (environment.production) { 33 | enableProdMode(); 34 | } 35 | 36 | document.addEventListener('DOMContentLoaded', () => { 37 | platformBrowserDynamic().bootstrapModule(AppModule) 38 | .catch(err => console.log(err)); 39 | }); 40 | 41 | ``` 42 | 43 | 44 | ## Install 45 | ```bash 46 | npm install --save @web-aid-kit/ngx-image-gallery 47 | ``` 48 | 49 | ## Import 50 | ```typescript 51 | import { NgxImageGalleryModule } from '@web-aid-kit/ngx-image-gallery'; 52 | 53 | @NgModule({ 54 | ..., 55 | imports: [ 56 | NgxImageGalleryModule, 57 | ... 58 | ] 59 | }) 60 | export class AppModule { } 61 | ``` 62 | 63 | ## Use 64 | 65 | ```html 66 | // app.component.html 67 | 68 | 77 | ``` 78 | 79 | ## Configure 80 | ```ts 81 | import { Component, OnInit, ViewChild } from '@angular/core'; 82 | import { NgxImageGalleryComponent, GALLERY_IMAGE, GALLERY_CONF } from '@web-aid-kit/ngx-image-gallery'; 83 | 84 | @Component({ 85 | selector: 'app-root', 86 | templateUrl: './app.component.html', 87 | styleUrls: ['./app.component.scss'] 88 | }) 89 | export class AppComponent implements OnInit { 90 | // get reference to gallery component 91 | @ViewChild(NgxImageGalleryComponent) ngxImageGallery: NgxImageGalleryComponent; 92 | 93 | // gallery configuration 94 | conf: GALLERY_CONF = { 95 | imageOffset: '0px', 96 | showDeleteControl: false, 97 | showImageTitle: false, 98 | }; 99 | 100 | // gallery images 101 | images: GALLERY_IMAGE[] = [ 102 | { 103 | url: "https://images.pexels.com/photos/669013/pexels-photo-669013.jpeg?w=1260", 104 | altText: 'woman-in-black-blazer-holding-blue-cup', 105 | title: 'woman-in-black-blazer-holding-blue-cup', 106 | thumbnailUrl: "https://images.pexels.com/photos/669013/pexels-photo-669013.jpeg?w=60" 107 | }, 108 | { 109 | url: "https://images.pexels.com/photos/669006/pexels-photo-669006.jpeg?w=1260", 110 | altText: 'two-woman-standing-on-the-ground-and-staring-at-the-mountain', 111 | extUrl: 'https://www.pexels.com/photo/two-woman-standing-on-the-ground-and-staring-at-the-mountain-669006/', 112 | thumbnailUrl: "https://images.pexels.com/photos/669006/pexels-photo-669006.jpeg?w=60" 113 | }, 114 | ]; 115 | 116 | constructor(){} 117 | 118 | ngOnInit() {} 119 | 120 | // METHODS 121 | // open gallery 122 | openGallery(index: number = 0) { 123 | this.ngxImageGallery.open(index); 124 | } 125 | 126 | // close gallery 127 | closeGallery() { 128 | this.ngxImageGallery.close(); 129 | } 130 | 131 | // set new active(visible) image in gallery 132 | newImage(index: number = 0) { 133 | this.ngxImageGallery.setActiveImage(index); 134 | } 135 | 136 | // next image in gallery 137 | nextImage(index: number = 0) { 138 | this.ngxImageGallery.next(); 139 | } 140 | 141 | // prev image in gallery 142 | prevImage(index: number = 0) { 143 | this.ngxImageGallery.prev(); 144 | } 145 | 146 | /**************************************************/ 147 | 148 | // EVENTS 149 | // callback on gallery opened 150 | galleryOpened(index) { 151 | console.info('Gallery opened at index ', index); 152 | } 153 | 154 | // callback on gallery closed 155 | galleryClosed() { 156 | console.info('Gallery closed.'); 157 | } 158 | 159 | // callback on gallery image clicked 160 | galleryImageClicked(index) { 161 | console.info('Gallery image clicked with index ', index); 162 | } 163 | 164 | // callback on gallery image changed 165 | galleryImageChanged(index) { 166 | console.info('Gallery image changed to index ', index); 167 | } 168 | 169 | // callback on user clicked delete button 170 | deleteImage(index) { 171 | console.info('Delete image at index ', index); 172 | } 173 | } 174 | ``` 175 | 176 | ### Interfaces 177 | ```ts 178 | // gallery configuration 179 | export interface GALLERY_CONF { 180 | imageBorderRadius?: string; // css border radius of image (default 3px) 181 | imageOffset?: string; // add gap between image and it's container (default 20px) 182 | imagePointer? :boolean; // show a pointer on image, should be true when handling onImageClick event (default false) 183 | showDeleteControl?: boolean; // show image delete icon (default false) 184 | showCloseControl?: boolean; // show gallery close icon (default true) 185 | showExtUrlControl?: boolean; // show image external url icon (default true) 186 | showImageTitle?: boolean; // show image title text (default true) 187 | showThumbnails?: boolean; // show thumbnails (default true) 188 | closeOnEsc?: boolean; // close gallery on `Esc` button press (default true) 189 | reactToKeyboard?: boolean; // change image on keyboard arrow press (default true) 190 | reactToMouseWheel?: boolean; // change image on mouse wheel scroll (default true) 191 | reactToRightClick?: boolean; // disable right click on gallery (default false) 192 | thumbnailSize?: number; // thumbnail size (default 30) 193 | backdropColor?: string; // gallery backdrop (background) color (default rgba(13,13,14,0.85)) 194 | inline?: boolean; // make gallery inline (default false) 195 | showArrows?: boolean; // show prev / next arrows (default true) 196 | } 197 | 198 | // gallery image 199 | export interface GALLERY_IMAGE { 200 | url: string; // url of the image 201 | thumbnailUrl?: string; // thumbnail url (recommended), if not present, gallery will use `url` property to get thumbnail image. 202 | altText?: string; // alt text for image 203 | title?: string; // title of the image 204 | extUrl?: string; // external url of image 205 | extUrlTarget?: string; // external url target e.g. '_blank', '_self' etc. 206 | } 207 | ``` 208 | 209 | > All properties ending with `?` are optional. 210 | 211 | # Make gallery inline 212 | You can make gallery **inline** like a carousel by setting `conf.inline` to `true` but make sure to change `conf.backdropColor` as well if you need white backdrop color. Also `width` and `height` of the gallery can be adjusted by manually applying css styles with `!important` flag on gallery element. 213 | 214 | # Dynamic Update 215 | You can update gallery images `images` and gallery configuration `conf` anytime you want even when gallery is opened but due to Angular's change detection restrictions you must assign these variable to new value instead of changing internal properties as mentioned below. 216 | 217 | ```ts 218 | // change images 219 | this.images = this.images.concat([...]); 220 | 221 | // change conf 222 | this.conf = {...}; 223 | ``` -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../../coverage/ngx-image-gallery'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../../dist/ngx-image-gallery", 4 | "lib": { 5 | "entryFile": "src/public-api.ts" 6 | } 7 | } -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@web-aid-kit/ngx-image-gallery", 3 | "version": "v1.0.0-beta", 4 | "peerDependencies": { 5 | "@angular/common": "^9.0.7", 6 | "@angular/core": "^9.0.7", 7 | "hammerjs": "^2.0.8", 8 | "lodash": "^4.17.15", 9 | "tslib": "^1.10.0" 10 | } 11 | } -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/src/lib/components/ngx-image-gallery/ngx-image-gallery.component.html: -------------------------------------------------------------------------------- 1 | 2 |
4 | 5 |
6 | 7 |
10 | 13 |
14 | 15 | 16 |
17 | 18 | 19 | 20 | 27 | 28 | 34 | 35 | 36 |
37 |
38 | 39 | 40 |
41 |
{{ activeImage.title }} 46 |
47 | 48 |
49 |
50 |
60 | 61 |
62 |
63 |
64 |
65 |
66 | 67 | 68 | 69 |
71 |
73 | 74 |
75 | 78 | 79 | 80 |
81 | 82 |
83 |
84 | 85 |
86 |
88 | 89 |
90 |
91 | -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/src/lib/components/ngx-image-gallery/ngx-image-gallery.component.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | exports.__esModule = true; 9 | var core_1 = require("@angular/core"); 10 | var lodash_1 = require("lodash"); 11 | // key codes to react 12 | var KEY_CODES = { 13 | 37: 'LEFT', 14 | 39: 'RIGHT', 15 | 27: 'ESC' 16 | }; 17 | // default gallery configuration 18 | var DEFAULT_CONF = { 19 | imageBorderRadius: '3px', 20 | imageOffset: '20px', 21 | imagePointer: false, 22 | showDeleteControl: false, 23 | showCloseControl: true, 24 | showExtUrlControl: true, 25 | showImageTitle: true, 26 | showThumbnails: true, 27 | closeOnEsc: true, 28 | reactToKeyboard: true, 29 | reactToMouseWheel: true, 30 | reactToRightClick: false, 31 | thumbnailSize: 30, 32 | backdropColor: 'rgba(13,13,14,0.85)', 33 | inline: false, 34 | showArrows: true 35 | }; 36 | var NgxImageGalleryComponent = (function () { 37 | /***************************************************/ 38 | function NgxImageGalleryComponent(galleryElem, renderer) { 39 | var _this = this; 40 | this.galleryElem = galleryElem; 41 | this.renderer = renderer; 42 | // gallery opened memory 43 | this.opened = false; 44 | // gallery configuration 45 | this.conf = {}; 46 | // gallery images 47 | this.images = []; 48 | // event emmiters 49 | this.onOpen = new core_1.EventEmitter(); 50 | this.onClose = new core_1.EventEmitter(); 51 | this.onDelete = new core_1.EventEmitter(); 52 | this.onImageChange = new core_1.EventEmitter(); 53 | this.onImageClicked = new core_1.EventEmitter(); 54 | /***************************************************/ 55 | // loading animation memory 56 | this.loading = false; 57 | // current active image index 58 | this.activeImageIndex = null; 59 | // thumbnail margin and scroll position 60 | this.thumbnailMargin = '0px 8px'; 61 | this.thumbnailsScrollerLeftMargin = '0px'; 62 | // adjust thumbnail margin to perfectly fit viewport 63 | this.fitThumbnails = lodash_1.debounce(function () { 64 | // if thumbnails not visible, return false 65 | if (_this.conf.showThumbnails == false) 66 | return false; 67 | var thumbnailParams = _this.thumbnailsRenderParams; 68 | _this.thumbnailMargin = '0 ' + (thumbnailParams.newThumbnailMargin / 2) + 'px'; 69 | }, 300); 70 | // debounced prev 71 | this.debouncedPrev = lodash_1.debounce(function () { return _this.prev(); }, 100, { 'leading': true, 'trailing': false }); 72 | // debounced next 73 | this.debouncedNext = lodash_1.debounce(function () { return _this.next(); }, 100, { 'leading': true, 'trailing': false }); 74 | } 75 | Object.defineProperty(NgxImageGalleryComponent.prototype, "activeImage", { 76 | // active image 77 | get: function () { 78 | return this.images[this.activeImageIndex]; 79 | }, 80 | enumerable: true, 81 | configurable: true 82 | }); 83 | Object.defineProperty(NgxImageGalleryComponent.prototype, "onFirstImage", { 84 | // if gallery is on : first image 85 | get: function () { 86 | return this.activeImageIndex == 0; 87 | }, 88 | enumerable: true, 89 | configurable: true 90 | }); 91 | Object.defineProperty(NgxImageGalleryComponent.prototype, "onLastImage", { 92 | // if gallery is on : last image 93 | get: function () { 94 | return this.activeImageIndex == (this.images.length - 1); 95 | }, 96 | enumerable: true, 97 | configurable: true 98 | }); 99 | Object.defineProperty(NgxImageGalleryComponent.prototype, "thumbnailsRenderParams", { 100 | // get thumbnails viewport rendering parameters 101 | get: function () { 102 | var thumbnailsContainerWidth = this.thumbnailsElem.nativeElement.offsetWidth; 103 | var thumbnailMargin = 16; 104 | var thumbnailSize = thumbnailMargin + this.conf.thumbnailSize; 105 | var thumbnailsInView = Math.floor(thumbnailsContainerWidth / thumbnailSize); 106 | var extraSpaceInThumbnailsContainer = thumbnailsContainerWidth - (thumbnailsInView * thumbnailSize); 107 | var extraMargin = extraSpaceInThumbnailsContainer / thumbnailsInView; 108 | var newThumbnailMargin = thumbnailMargin + extraMargin; 109 | var newThumbnailSize = newThumbnailMargin + this.conf.thumbnailSize; 110 | var relativePositionOfActiveImageThumbnailToScroller = thumbnailsInView - (thumbnailsInView - this.activeImageIndex); 111 | var thumbnailsScrollerLeftMargin; 112 | if (relativePositionOfActiveImageThumbnailToScroller > thumbnailsInView - 2) { 113 | var outThumbnails = ((this.activeImageIndex + 1) - thumbnailsInView) + 1; 114 | if (this.activeImageIndex != (this.images.length - 1)) { 115 | thumbnailsScrollerLeftMargin = '-' + (newThumbnailSize * outThumbnails) + 'px'; 116 | } 117 | else { 118 | thumbnailsScrollerLeftMargin = '-' + (newThumbnailSize * (outThumbnails - 1)) + 'px'; 119 | } 120 | } 121 | else { 122 | thumbnailsScrollerLeftMargin = '0px'; 123 | } 124 | return { 125 | thumbnailsInView: thumbnailsInView, 126 | newThumbnailMargin: newThumbnailMargin, 127 | newThumbnailSize: newThumbnailSize, 128 | thumbnailsScrollerLeftMargin: thumbnailsScrollerLeftMargin 129 | }; 130 | }, 131 | enumerable: true, 132 | configurable: true 133 | }); 134 | // set gallery configuration 135 | NgxImageGalleryComponent.prototype.setGalleryConf = function (conf) { 136 | this.conf = lodash_1.assign(DEFAULT_CONF, conf); 137 | }; 138 | // load image and return promise 139 | NgxImageGalleryComponent.prototype.loadImage = function (index) { 140 | var _this = this; 141 | var galleryImage = this.images[index]; 142 | // check if image is cached 143 | if (galleryImage._cached) { 144 | return Promise.resolve(index); 145 | } 146 | else { 147 | return new Promise(function (resolve, reject) { 148 | _this.loading = true; 149 | var image = new Image(); 150 | image.src = galleryImage.url; 151 | image.onload = function () { 152 | _this.loading = false; 153 | galleryImage._cached = true; 154 | resolve(index); 155 | }; 156 | image.onerror = function (error) { 157 | _this.loading = false; 158 | reject(error); 159 | }; 160 | }); 161 | } 162 | }; 163 | // activate image (set active image) 164 | NgxImageGalleryComponent.prototype.activateImage = function (imageIndex) { 165 | var _this = this; 166 | // prevent loading if already loading 167 | if (this.loading) 168 | return false; 169 | // emit event 170 | this.onImageChange.emit(imageIndex); 171 | this.loadImage(imageIndex) 172 | .then(function (_imageIndex) { 173 | _this.activeImageIndex = _imageIndex; 174 | // scroll thumbnails 175 | setTimeout(function () { 176 | _this.fitThumbnails(); 177 | setTimeout(function () { return _this.scrollThumbnails(); }, 300); 178 | }); 179 | })["catch"](function (error) { return console.warn(error); }); 180 | }; 181 | // scroll thumbnails to perfectly position active image thumbnail in viewport 182 | NgxImageGalleryComponent.prototype.scrollThumbnails = function () { 183 | // if thumbnails not visible, return false 184 | if (this.conf.showThumbnails == false) 185 | return false; 186 | var thumbnailParams = this.thumbnailsRenderParams; 187 | this.thumbnailsScrollerLeftMargin = thumbnailParams.thumbnailsScrollerLeftMargin; 188 | }; 189 | // keyboard event 190 | NgxImageGalleryComponent.prototype.onKeyboardInput = function (event) { 191 | if (this.conf.reactToKeyboard && this.opened && !this.loading) { 192 | if (KEY_CODES[event.keyCode] == 'RIGHT') { 193 | this.next(); 194 | } 195 | else if (KEY_CODES[event.keyCode] == 'LEFT') { 196 | this.prev(); 197 | } 198 | else if ((KEY_CODES[event.keyCode] == 'ESC') && this.conf.closeOnEsc) { 199 | this.close(); 200 | } 201 | } 202 | }; 203 | // window resize event 204 | NgxImageGalleryComponent.prototype.onWindowResize = function (event) { 205 | var _this = this; 206 | if (this.opened && !this.loading) { 207 | this.fitThumbnails(); 208 | setTimeout(function () { return _this.scrollThumbnails(); }, 300); 209 | } 210 | }; 211 | NgxImageGalleryComponent.prototype.ngOnInit = function () { 212 | // create final gallery configuration 213 | this.setGalleryConf(this.conf); 214 | // apply backdrop color 215 | this.renderer.setStyle(this.galleryElem.nativeElement, 'background-color', this.conf.backdropColor); 216 | // gallery inline class and auto open 217 | if (this.conf.inline) { 218 | this.renderer.addClass(this.galleryElem.nativeElement, 'inline'); 219 | this.open(0); 220 | } 221 | }; 222 | NgxImageGalleryComponent.prototype.ngOnChanges = function (changes) { 223 | // when gallery configuration changes 224 | if (changes.conf && changes.conf.firstChange == false) { 225 | this.setGalleryConf(changes.conf.currentValue); 226 | // apply backdrop color 227 | this.renderer.setStyle(this.galleryElem.nativeElement, 'background-color', this.conf.backdropColor); 228 | // gallery inline class and auto open 229 | if ((changes.conf.previousValue.inline != true) && this.conf.inline) { 230 | this.renderer.addClass(this.galleryElem.nativeElement, 'inline'); 231 | this.open(0); 232 | } 233 | } 234 | // when gallery images changes 235 | if (changes.images && changes.images.firstChange == false) { 236 | this.images = changes.images.currentValue; 237 | if (this.images.length) { 238 | this.activateImage(0); 239 | } 240 | } 241 | }; 242 | /***************************************************/ 243 | // open gallery 244 | NgxImageGalleryComponent.prototype.open = function (index) { 245 | if (index === void 0) { index = 0; } 246 | if (this.images.length) { 247 | this.opened = true; 248 | // emit event 249 | this.onOpen.emit(index); 250 | // activate image at given index 251 | this.activateImage(index); 252 | } 253 | else { 254 | console.warn('No images provided to ngx-image-gallery!'); 255 | } 256 | }; 257 | // close gallery 258 | NgxImageGalleryComponent.prototype.close = function () { 259 | this.opened = false; 260 | this.activeImageIndex = 0; 261 | // emit event 262 | this.onClose.emit(); 263 | }; 264 | // change prev image 265 | NgxImageGalleryComponent.prototype.prev = function () { 266 | if (this.onFirstImage == false) { 267 | this.activateImage(this.activeImageIndex - 1); 268 | } 269 | }; 270 | // change next image 271 | NgxImageGalleryComponent.prototype.next = function () { 272 | if (this.onLastImage == false) { 273 | this.activateImage(this.activeImageIndex + 1); 274 | } 275 | }; 276 | // set image (activate) 277 | NgxImageGalleryComponent.prototype.setActiveImage = function (index) { 278 | this.activateImage(index); 279 | }; 280 | // delete image 281 | NgxImageGalleryComponent.prototype.deleteImage = function (index) { 282 | this.onDelete.emit(index); 283 | }; 284 | // mouse wheel up (prev image) 285 | NgxImageGalleryComponent.prototype.mouseWheelUp = function () { 286 | if (this.conf.reactToMouseWheel) { 287 | this.debouncedNext(); 288 | } 289 | }; 290 | // mouse wheel down (next image) 291 | NgxImageGalleryComponent.prototype.mouseWheelDown = function () { 292 | if (this.conf.reactToMouseWheel) { 293 | this.debouncedPrev(); 294 | } 295 | }; 296 | // click on image 297 | NgxImageGalleryComponent.prototype.clickOnImage = function (index) { 298 | this.onImageClicked.emit(index); 299 | }; 300 | // right click on image 301 | NgxImageGalleryComponent.prototype.rightClickOnImage = function (event) { 302 | event.stopPropagation(); 303 | return this.conf.reactToRightClick; 304 | }; 305 | return NgxImageGalleryComponent; 306 | }()); 307 | __decorate([ 308 | core_1.HostBinding('class.active') 309 | ], NgxImageGalleryComponent.prototype, "opened"); 310 | __decorate([ 311 | core_1.Input() 312 | ], NgxImageGalleryComponent.prototype, "conf"); 313 | __decorate([ 314 | core_1.Input() 315 | ], NgxImageGalleryComponent.prototype, "images"); 316 | __decorate([ 317 | core_1.Output() 318 | ], NgxImageGalleryComponent.prototype, "onOpen"); 319 | __decorate([ 320 | core_1.Output() 321 | ], NgxImageGalleryComponent.prototype, "onClose"); 322 | __decorate([ 323 | core_1.Output() 324 | ], NgxImageGalleryComponent.prototype, "onDelete"); 325 | __decorate([ 326 | core_1.Output() 327 | ], NgxImageGalleryComponent.prototype, "onImageChange"); 328 | __decorate([ 329 | core_1.Output() 330 | ], NgxImageGalleryComponent.prototype, "onImageClicked"); 331 | __decorate([ 332 | core_1.ViewChild('thumbnails') 333 | ], NgxImageGalleryComponent.prototype, "thumbnailsElem"); 334 | __decorate([ 335 | core_1.HostListener('window:keydown', ['$event']) 336 | ], NgxImageGalleryComponent.prototype, "onKeyboardInput"); 337 | __decorate([ 338 | core_1.HostListener('window:resize', ['$event']) 339 | ], NgxImageGalleryComponent.prototype, "onWindowResize"); 340 | NgxImageGalleryComponent = __decorate([ 341 | core_1.Component({ 342 | selector: 'ngx-image-gallery', 343 | templateUrl: './ngx-image-gallery.component.html', 344 | styleUrls: ['./ngx-image-gallery.component.scss'] 345 | }) 346 | ], NgxImageGalleryComponent); 347 | exports.NgxImageGalleryComponent = NgxImageGalleryComponent; 348 | -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/src/lib/components/ngx-image-gallery/ngx-image-gallery.component.scss: -------------------------------------------------------------------------------- 1 | // zoom scale in 2 | @keyframes zoomScaleIn { 3 | 0%{ 4 | transform: scale(0.99); 5 | opacity: 0; 6 | } 7 | 8 | 100%{ 9 | transform: scale(1); 10 | opacity: 1; 11 | } 12 | } 13 | 14 | // thumbnail box shadow animation 15 | @keyframes thumbShadowAnimation { 16 | 0%{ 17 | box-shadow: 0 0 3px 2px rgba(255,255,255,0.05); 18 | } 19 | 20 | 100%{ 21 | box-shadow: 0 0 3px 2px rgba(255,255,255,0.2); 22 | } 23 | } 24 | 25 | // prevent drag, highlight and select 26 | @mixin no-select{ 27 | backface-visibility: hidden; 28 | -webkit-backface-visibility: hidden; 29 | -webkit-touch-callout: none; 30 | -webkit-user-select: none; 31 | -moz-user-select: none; 32 | -ms-user-select: none; 33 | user-select: none; 34 | user-drag: none; 35 | -webkit-user-drag: none; 36 | } 37 | 38 | // click feedback 39 | @keyframes clickFeedback1 { 40 | 0% { 41 | opacity: 1; 42 | transform: scale3d(0.5, 0.5, 1); 43 | } 44 | 100% { 45 | opacity: 0; 46 | transform: scale3d(1.1, 1.1, 1); 47 | } 48 | } 49 | @keyframes clickFeedback2 { 50 | 0% { 51 | opacity: 1; 52 | transform: scale3d(0.5, 0.5, 1); 53 | } 54 | 50%{ 55 | opacity: 0; 56 | transform: scale3d(1.2, 1.2, 1); 57 | } 58 | 100%{ 59 | opacity: 0; 60 | transform: scale3d(1.2, 1.2, 1); 61 | } 62 | } 63 | .feedback{ 64 | position: absolute; 65 | z-index: 1; 66 | left: 0; 67 | top: 0; 68 | right: 0; 69 | bottom: 0; 70 | 71 | &:before, 72 | &:after { 73 | position: absolute; 74 | top: 50%; 75 | left: 50%; 76 | margin: -30px 0 0 -30px; 77 | width: 60px; 78 | height: 60px; 79 | border-radius: 50%; 80 | content: ''; 81 | opacity: 0; 82 | pointer-events: none; 83 | box-shadow: 0 0 0 2px rgba(111,148,182,0.5); 84 | } 85 | 86 | &:active{ 87 | &:before{ 88 | animation: clickFeedback1 0.5s forwards; 89 | } 90 | 91 | &:after{ 92 | animation: clickFeedback2 0.5s forwards; 93 | } 94 | } 95 | } 96 | 97 | /**************************************************/ 98 | 99 | :host{ 100 | display: none; 101 | position: fixed; 102 | z-index: 10000; 103 | left: 0; 104 | top: 0; 105 | right: 0; 106 | bottom: 0; 107 | 108 | // inline gallery 109 | &.inline{ 110 | display: block; 111 | position: relative; 112 | width: 100%; 113 | height: 500px; 114 | } 115 | 116 | &.active{ 117 | display: block; 118 | } 119 | 120 | >.galleria{ 121 | position: absolute; 122 | left: 80px; 123 | right: 80px; 124 | top: 0; 125 | bottom: 0; 126 | z-index: 1; 127 | display: flex; 128 | flex-direction: column; 129 | animation: zoomScaleIn 0.2s 1 forwards; 130 | 131 | >.images-container{ 132 | flex: 1; 133 | width: 100%; 134 | position: relative; 135 | 136 | >.image{ 137 | position: absolute; 138 | left: 0; 139 | right: 0; 140 | top: 0; 141 | bottom: 0; 142 | display: none; 143 | 144 | &.active{ 145 | display: block; 146 | } 147 | 148 | >img{ 149 | position: absolute; 150 | left: 0; 151 | right: 0; 152 | top: 0; 153 | bottom: 0; 154 | margin: auto; 155 | max-width: 100%; 156 | max-height: 100%; 157 | animation: zoomScaleIn 0.2s 1 forwards; 158 | @include no-select; 159 | } 160 | } 161 | 162 | >.loading-animation{ 163 | position: absolute; 164 | left: 0; 165 | top: 0; 166 | right: 0; 167 | bottom: 0; 168 | z-index: 100; 169 | display: flex; 170 | justify-content: center; 171 | align-items: center; 172 | 173 | >svg{ 174 | flex: none; 175 | width: 100px; 176 | height: 100px; 177 | } 178 | } 179 | } 180 | 181 | >.info-container{ 182 | flex: none; 183 | width: 100%; 184 | display: flex; 185 | flex-direction: column; 186 | align-items: center; 187 | 188 | >.title{ 189 | padding-top: 30px; 190 | line-height: 1.4; 191 | font-size: 13px; 192 | color: #fff; 193 | text-align: center; 194 | font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; 195 | 196 | &.dark{ 197 | color: #222; 198 | } 199 | } 200 | 201 | >.thumbnails{ 202 | padding-top: 20px; 203 | padding-bottom: 20px; 204 | overflow: hidden; 205 | white-space: nowrap; 206 | width: auto; 207 | margin: 0 auto; 208 | max-width: 100%; 209 | 210 | .thumbnails-scroller{ 211 | white-space: nowrap; 212 | transition: all 0.3s ease; 213 | 214 | >.thumbnail{ 215 | display: inline-block; 216 | border-radius: 100%; 217 | vertical-align: middle; 218 | background-color: #999; 219 | opacity: 0.5; 220 | filter: grayscale(100%); 221 | background-size: cover; 222 | background-position: center top; 223 | cursor: pointer; 224 | position: relative; 225 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 226 | outline: none; 227 | transition: all 0.3s ease; 228 | @include no-select; 229 | 230 | &.active, 231 | &:hover{ 232 | filter: grayscale(30%); 233 | 234 | &:after{ 235 | content: ""; 236 | display: block; 237 | position: absolute; 238 | left: -3px; 239 | top: -3px; 240 | right: -3px; 241 | bottom: -3px; 242 | border-radius: 100%; 243 | overflow: hidden; 244 | animation: thumbShadowAnimation 1s infinite alternate; 245 | } 246 | } 247 | 248 | &.active{ 249 | opacity: 1; 250 | filter: grayscale(0%); 251 | } 252 | } 253 | } 254 | } 255 | } 256 | } 257 | 258 | >.control{ 259 | z-index: 20; 260 | @include no-select; 261 | 262 | &.arrow{ 263 | position: absolute; 264 | top: 50%; 265 | margin-top: -60px; 266 | width: 50px; 267 | height: 50px; 268 | background-size: 100% 100%; 269 | background-repeat: no-repeat; 270 | overflow: hidden; 271 | cursor: pointer; 272 | transition: all 100ms ease; 273 | 274 | &.disabled{ 275 | opacity: 0.3; 276 | } 277 | 278 | &:not(.disabled):active{ 279 | width: 60px; 280 | } 281 | 282 | &.left{ 283 | left: 0; 284 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNDc3LjE3NSA0NzcuMTc1IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0NzcuMTc1IDQ3Ny4xNzU7IiB4bWw6c3BhY2U9InByZXNlcnZlIiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPg0KPGc+DQoJPHBhdGggZD0iTTE0NS4xODgsMjM4LjU3NWwyMTUuNS0yMTUuNWM1LjMtNS4zLDUuMy0xMy44LDAtMTkuMXMtMTMuOC01LjMtMTkuMSwwbC0yMjUuMSwyMjUuMWMtNS4zLDUuMy01LjMsMTMuOCwwLDE5LjFsMjI1LjEsMjI1ICAgYzIuNiwyLjYsNi4xLDQsOS41LDRzNi45LTEuMyw5LjUtNGM1LjMtNS4zLDUuMy0xMy44LDAtMTkuMUwxNDUuMTg4LDIzOC41NzV6IiBmaWxsPSIjRkZGRkZGIi8+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8L3N2Zz4NCg=='); 285 | 286 | &.dark{ 287 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNi4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkNhcGFfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHdpZHRoPSI1MTJweCIgaGVpZ2h0PSI1MTJweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDUxMiA1MTIiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPGc+DQoJPHBhdGggZmlsbD0iIzk5OTk5OSIgZD0iTTE1NS43ODQsMjU1Ljk4NkwzODcuMDEyLDI0Ljc1OWM1LjY4Ny01LjY4Nyw1LjY4Ny0xNC44MDcsMC0yMC40OTRjLTUuNjg4LTUuNjg3LTE0LjgwNy01LjY4Ny0yMC40OTQsMA0KCQlMMTI0Ljk4OSwyNDUuNzkzYy01LjY4Nyw1LjY4Ny01LjY4NywxNC44MDcsMCwyMC40OTRsMjQxLjUyOCwyNDEuNDIxYzIuNzksMi43OSw2LjU0NSw0LjI5MiwxMC4xOTMsNC4yOTINCgkJczcuNDAzLTEuMzk1LDEwLjE5My00LjI5MmM1LjY4Ny01LjY4Nyw1LjY4Ny0xNC44MDcsMC0yMC40OTRMMTU1Ljc4NCwyNTUuOTg2eiIvPg0KPC9nPg0KPC9zdmc+DQo='); 288 | } 289 | } 290 | 291 | &.right{ 292 | right: 0; 293 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNDc3LjE3NSA0NzcuMTc1IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0NzcuMTc1IDQ3Ny4xNzU7IiB4bWw6c3BhY2U9InByZXNlcnZlIiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPg0KPGc+DQoJPHBhdGggZD0iTTM2MC43MzEsMjI5LjA3NWwtMjI1LjEtMjI1LjFjLTUuMy01LjMtMTMuOC01LjMtMTkuMSwwcy01LjMsMTMuOCwwLDE5LjFsMjE1LjUsMjE1LjVsLTIxNS41LDIxNS41ICAgYy01LjMsNS4zLTUuMywxMy44LDAsMTkuMWMyLjYsMi42LDYuMSw0LDkuNSw0YzMuNCwwLDYuOS0xLjMsOS41LTRsMjI1LjEtMjI1LjFDMzY1LjkzMSwyNDIuODc1LDM2NS45MzEsMjM0LjI3NSwzNjAuNzMxLDIyOS4wNzV6ICAgIiBmaWxsPSIjRkZGRkZGIi8+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8L3N2Zz4NCg=='); 294 | 295 | &.dark{ 296 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNi4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkNhcGFfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHdpZHRoPSI1MTJweCIgaGVpZ2h0PSI1MTJweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDUxMiA1MTIiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPGc+DQoJPHBhdGggZmlsbD0iIzk5OTk5OSIgZD0iTTM4Ny4wNTgsMjQ1Ljc5M0wxNDUuNTMsNC4yNjVjLTUuNjg3LTUuNjg3LTE0LjgwNy01LjY4Ny0yMC40OTQsMHMtNS42ODcsMTQuODA3LDAsMjAuNDk0bDIzMS4yMjgsMjMxLjIyOA0KCQlMMTI1LjAzNiw0ODcuMjE0Yy01LjY4Nyw1LjY4OC01LjY4NywxNC44MDgsMCwyMC40OTRjMi43OSwyLjc5LDYuNTQ1LDQuMjkyLDEwLjE5Myw0LjI5MmMzLjY0OCwwLDcuNDAzLTEuMzk1LDEwLjE5My00LjI5Mg0KCQlMMzg2Ljk1LDI2Ni4xOEMzOTIuNjM3LDI2MC42MDEsMzkyLjYzNywyNTEuMzczLDM4Ny4wNTgsMjQ1Ljc5M3oiLz4NCjwvZz4NCjwvc3ZnPg0K'); 297 | } 298 | } 299 | } 300 | 301 | &.left-top, 302 | &.right-top{ 303 | position: absolute; 304 | top: 20px; 305 | 306 | &.left-top{ 307 | left: 10px; 308 | } 309 | 310 | &.right-top{ 311 | right: 10px; 312 | } 313 | 314 | >.delete-img, 315 | >.ext-url, 316 | >.close{ 317 | position: relative; 318 | display: inline-block; 319 | width: 30px; 320 | height: 30px; 321 | cursor: pointer; 322 | text-decoration: none; 323 | color: #fff; 324 | vertical-align: bottom; 325 | transition: background-color .3s ease-in-out; 326 | 327 | &:hover{ 328 | background-color: rgba(255,255,255,.1); 329 | } 330 | 331 | &:before{ 332 | content: ""; 333 | display: block; 334 | position: absolute; 335 | top: 5px; 336 | right: 5px; 337 | bottom: 5px; 338 | left: 5px; 339 | background-size: 100% 100%; 340 | background-repeat: no-repeat; 341 | } 342 | 343 | &.delete-img{ 344 | &:before{ 345 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDU5IDU5IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1OSA1OTsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSI1MTJweCIgaGVpZ2h0PSI1MTJweCI+CjxwYXRoIGQ9Ik01Mi41LDZIMzguNDU2Yy0wLjExLTEuMjUtMC40OTUtMy4zNTgtMS44MTMtNC43MTFDMzUuODA5LDAuNDM0LDM0Ljc1MSwwLDMzLjQ5OSwwSDIzLjVjLTEuMjUyLDAtMi4zMSwwLjQzNC0zLjE0NCwxLjI4OSAgQzE5LjAzOCwyLjY0MiwxOC42NTMsNC43NSwxOC41NDMsNkg2LjVjLTAuNTUyLDAtMSwwLjQ0Ny0xLDFzMC40NDgsMSwxLDFoMi4wNDFsMS45MTUsNDYuMDIxQzEwLjQ5Myw1NS43NDMsMTEuNTY1LDU5LDE1LjM2NCw1OSAgaDI4LjI3MmMzLjc5OSwwLDQuODcxLTMuMjU3LDQuOTA3LTQuOTU4TDUwLjQ1OSw4SDUyLjVjMC41NTIsMCwxLTAuNDQ3LDEtMVM1My4wNTIsNiw1Mi41LDZ6IE0yMC41LDUwYzAsMC41NTMtMC40NDgsMS0xLDEgIHMtMS0wLjQ0Ny0xLTFWMTdjMC0wLjU1MywwLjQ0OC0xLDEtMXMxLDAuNDQ3LDEsMVY1MHogTTMwLjUsNTBjMCwwLjU1My0wLjQ0OCwxLTEsMXMtMS0wLjQ0Ny0xLTFWMTdjMC0wLjU1MywwLjQ0OC0xLDEtMSAgczEsMC40NDcsMSwxVjUweiBNNDAuNSw1MGMwLDAuNTUzLTAuNDQ4LDEtMSwxcy0xLTAuNDQ3LTEtMVYxN2MwLTAuNTUzLDAuNDQ4LTEsMS0xczEsMC40NDcsMSwxVjUweiBNMjEuNzkyLDIuNjgxICBDMjIuMjQsMi4yMjMsMjIuNzk5LDIsMjMuNSwyaDkuOTk5YzAuNzAxLDAsMS4yNiwwLjIyMywxLjcwOCwwLjY4MWMwLjgwNSwwLjgyMywxLjEyOCwyLjI3MSwxLjI0LDMuMzE5SDIwLjU1MyAgQzIwLjY2NSw0Ljk1MiwyMC45ODgsMy41MDQsMjEuNzkyLDIuNjgxeiIgZmlsbD0iI0ZGRkZGRiIvPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K'); 346 | } 347 | 348 | &.dark{ 349 | &:before{ 350 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDU5IDU5IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1OSA1OTsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSI1MTJweCIgaGVpZ2h0PSI1MTJweCI+CjxwYXRoIGQ9Ik01Mi41LDZIMzguNDU2Yy0wLjExLTEuMjUtMC40OTUtMy4zNTgtMS44MTMtNC43MTFDMzUuODA5LDAuNDM0LDM0Ljc1MSwwLDMzLjQ5OSwwSDIzLjVjLTEuMjUyLDAtMi4zMSwwLjQzNC0zLjE0NCwxLjI4OSAgQzE5LjAzOCwyLjY0MiwxOC42NTMsNC43NSwxOC41NDMsNkg2LjVjLTAuNTUyLDAtMSwwLjQ0Ny0xLDFzMC40NDgsMSwxLDFoMi4wNDFsMS45MTUsNDYuMDIxQzEwLjQ5Myw1NS43NDMsMTEuNTY1LDU5LDE1LjM2NCw1OSAgaDI4LjI3MmMzLjc5OSwwLDQuODcxLTMuMjU3LDQuOTA3LTQuOTU4TDUwLjQ1OSw4SDUyLjVjMC41NTIsMCwxLTAuNDQ3LDEtMVM1My4wNTIsNiw1Mi41LDZ6IE0yMC41LDUwYzAsMC41NTMtMC40NDgsMS0xLDEgIHMtMS0wLjQ0Ny0xLTFWMTdjMC0wLjU1MywwLjQ0OC0xLDEtMXMxLDAuNDQ3LDEsMVY1MHogTTMwLjUsNTBjMCwwLjU1My0wLjQ0OCwxLTEsMXMtMS0wLjQ0Ny0xLTFWMTdjMC0wLjU1MywwLjQ0OC0xLDEtMSAgczEsMC40NDcsMSwxVjUweiBNNDAuNSw1MGMwLDAuNTUzLTAuNDQ4LDEtMSwxcy0xLTAuNDQ3LTEtMVYxN2MwLTAuNTUzLDAuNDQ4LTEsMS0xczEsMC40NDcsMSwxVjUweiBNMjEuNzkyLDIuNjgxICBDMjIuMjQsMi4yMjMsMjIuNzk5LDIsMjMuNSwyaDkuOTk5YzAuNzAxLDAsMS4yNiwwLjIyMywxLjcwOCwwLjY4MWMwLjgwNSwwLjgyMywxLjEyOCwyLjI3MSwxLjI0LDMuMzE5SDIwLjU1MyAgQzIwLjY2NSw0Ljk1MiwyMC45ODgsMy41MDQsMjEuNzkyLDIuNjgxeiIgZmlsbD0iIzk5OTk5OSIvPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K'); 351 | } 352 | } 353 | } 354 | 355 | &.close{ 356 | &:before{ 357 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSI1MTJweCIgdmVyc2lvbj0iMS4xIiBoZWlnaHQ9IjUxMnB4IiB2aWV3Qm94PSIwIDAgNjQgNjQiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDY0IDY0Ij4NCiAgPGc+DQogICAgPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTI4Ljk0MSwzMS43ODZMMC42MTMsNjAuMTE0Yy0wLjc4NywwLjc4Ny0wLjc4NywyLjA2MiwwLDIuODQ5YzAuMzkzLDAuMzk0LDAuOTA5LDAuNTksMS40MjQsMC41OSAgIGMwLjUxNiwwLDEuMDMxLTAuMTk2LDEuNDI0LTAuNTlsMjguNTQxLTI4LjU0MWwyOC41NDEsMjguNTQxYzAuMzk0LDAuMzk0LDAuOTA5LDAuNTksMS40MjQsMC41OWMwLjUxNSwwLDEuMDMxLTAuMTk2LDEuNDI0LTAuNTkgICBjMC43ODctMC43ODcsMC43ODctMi4wNjIsMC0yLjg0OUwzNS4wNjQsMzEuNzg2TDYzLjQxLDMuNDM4YzAuNzg3LTAuNzg3LDAuNzg3LTIuMDYyLDAtMi44NDljLTAuNzg3LTAuNzg2LTIuMDYyLTAuNzg2LTIuODQ4LDAgICBMMzIuMDAzLDI5LjE1TDMuNDQxLDAuNTljLTAuNzg3LTAuNzg2LTIuMDYxLTAuNzg2LTIuODQ4LDBjLTAuNzg3LDAuNzg3LTAuNzg3LDIuMDYyLDAsMi44NDlMMjguOTQxLDMxLjc4NnoiLz4NCiAgPC9nPg0KPC9zdmc+DQo='); 358 | } 359 | 360 | &.dark{ 361 | &:before{ 362 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNi4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA1MTIgNTEyIiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnPg0KCTxwYXRoIGZpbGw9IiM5OTk5OTkiIGQ9Ik0yMzEuNTI4LDI1NC4yODhMNC45MDQsNDgwLjkxMmMtNi4yOTYsNi4yOTYtNi4yOTYsMTYuNDk2LDAsMjIuNzkyYzMuMTQ0LDMuMTUyLDcuMjcyLDQuNzIsMTEuMzkyLDQuNzINCgkJYzQuMTI4LDAsOC4yNDgtMS41NjcsMTEuMzkyLTQuNzJsMjI4LjMyOC0yMjguMzI4bDIyOC4zMjgsMjI4LjMyOGMzLjE1MiwzLjE1Miw3LjI3Miw0LjcyLDExLjM5Myw0LjcyDQoJCWM0LjExOSwwLDguMjQ4LTEuNTY3LDExLjM5Mi00LjcyYzYuMjk2LTYuMjk2LDYuMjk2LTE2LjQ5NiwwLTIyLjc5MkwyODAuNTEyLDI1NC4yODhMNTA3LjI4LDI3LjUwNA0KCQljNi4yOTYtNi4yOTYsNi4yOTYtMTYuNDk2LDAtMjIuNzkyYy02LjI5Ni02LjI4OC0xNi40OTYtNi4yODgtMjIuNzg0LDBMMjU2LjAyNCwyMzMuMkwyNy41MjgsNC43Mg0KCQljLTYuMjk2LTYuMjg4LTE2LjQ4OC02LjI4OC0yMi43ODQsMGMtNi4yOTYsNi4yOTYtNi4yOTYsMTYuNDk2LDAsMjIuNzkyTDIzMS41MjgsMjU0LjI4OHoiLz4NCjwvZz4NCjwvc3ZnPg0K'); 363 | } 364 | } 365 | } 366 | 367 | &.ext-url{ 368 | &:before{ 369 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE4LjEuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNTkxLjYgNTkxLjYiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDU5MS42IDU5MS42OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij4NCjxnPg0KCTxnPg0KCQk8cGF0aCBkPSJNNTgxLjQsMjA0Yy01LjcxMiwwLTEwLjIsNC40ODgtMTAuMiwxMC4ydjMyNi40YzAsMTYuOTMyLTEzLjY2OCwzMC42LTMwLjYsMzAuNkg1MWMtMTYuOTMyLDAtMzAuNi0xMy42NjgtMzAuNi0zMC42VjUxICAgIGMwLTE2LjkzMiwxMy42NjgtMzAuNiwzMC42LTMwLjZoMzI2LjRjNS43MTIsMCwxMC4yLTQuNDg4LDEwLjItMTAuMlMzODMuMTEyLDAsMzc3LjQsMEg1MUMyMi44NDgsMCwwLDIyLjg0OCwwLDUxdjQ4OS42ICAgIGMwLDI4LjE1MiwyMi44NDgsNTEsNTEsNTFoNDg5LjZjMjguMTUyLDAsNTEtMjIuODQ4LDUxLTUxVjIxNC4yQzU5MS42LDIwOC42OTIsNTg2LjkwOCwyMDQsNTgxLjQsMjA0eiIgZmlsbD0iI0ZGRkZGRiIvPg0KCQk8cGF0aCBkPSJNNTkxLjM5Niw4LjE2YzAtMC4yMDQtMC4yMDQtMC42MTItMC4yMDQtMC44MTZjMC0wLjQwOC0wLjIwNC0wLjYxMi0wLjQwOC0xLjAyYy0wLjIwNC0wLjQwOC0wLjQwOC0wLjYxMi0wLjYxMi0xLjAyICAgIGMtMC4yMDQtMC4yMDQtMC4yMDQtMC42MTItMC40MDgtMC44MTZjLTAuODE2LTEuMDItMS42MzItMi4wNC0yLjg1Ni0yLjg1NmMtMC4yMDQtMC4yMDQtMC42MTItMC4yMDQtMC44MTYtMC40MDggICAgYy0wLjQwOC0wLjIwNC0wLjYxMi0wLjQwOC0xLjAyLTAuNjEyYy0wLjQwOC0wLjIwNC0wLjYxMi0wLjIwNC0xLjAyLTAuNDA4Yy0wLjIwNCwwLTAuNjEyLTAuMjA0LTAuODE2LTAuMjA0ICAgIGMtMC42MTIsMC4yMDQtMS4yMjQsMC0xLjgzNiwwbDAsMEg0MzguNmMtNS43MTIsMC0xMC4yLDQuNDg4LTEwLjIsMTAuMnM0LjQ4OCwxMC4yLDEwLjIsMTAuMmgxMTguMTE2bC0zNzAuMjYsMzcwLjI2ICAgIGMtNC4wOCw0LjA4LTQuMDgsMTAuNDA0LDAsMTQuNDg0YzIuMDQsMi4wNCw0LjY5MiwzLjA2LDcuMTQsMy4wNmMyLjQ0OCwwLDUuMzA0LTEuMDIsNy4xNC0zLjA2TDU3MS4yLDM0Ljg4NFYxNTMgICAgYzAsNS43MTIsNC40ODgsMTAuMiwxMC4yLDEwLjJzMTAuMi00LjQ4OCwxMC4yLTEwLjJWMTAuMkM1OTEuNiw5LjU4OCw1OTEuMzk2LDguOTc2LDU5MS4zOTYsOC4xNnoiIGZpbGw9IiNGRkZGRkYiLz4NCgkJPHBhdGggZD0iTTUxLDQ1LjljLTIuODU2LDAtNS4xLDIuMjQ0LTUuMSw1LjF2MTQyLjhjMCwyLjg1NiwyLjI0NCw1LjEsNS4xLDUuMXM1LjEtMi4yNDQsNS4xLTUuMVY1Ni4xaDEzNy43ICAgIGMyLjg1NiwwLDUuMS0yLjI0NCw1LjEtNS4xcy0yLjI0NC01LjEtNS4xLTUuMUg1MXoiIGZpbGw9IiNGRkZGRkYiLz4NCgk8L2c+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8L3N2Zz4NCg=='); 370 | } 371 | 372 | &.dark{ 373 | &:before{ 374 | background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNi4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkNhcGFfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHdpZHRoPSI1MTJweCIgaGVpZ2h0PSI1MTJweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDUxMiA1MTIiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPGc+DQoJPGc+DQoJCTxwYXRoIGZpbGw9IiM5OTk5OTkiIGQ9Ik01MDMuMTczLDE3Ni41NTJjLTQuOTQ0LDAtOC44MjgsMy44ODQtOC44MjgsOC44Mjh2MjgyLjQ4M2MwLDE0LjY1My0xMS44MjksMjYuNDgyLTI2LjQ4MiwyNi40ODJINDQuMTM4DQoJCQljLTE0LjY1MywwLTI2LjQ4Mi0xMS44MjktMjYuNDgyLTI2LjQ4MlY0NC4xMzhjMC0xNC42NTMsMTEuODI5LTI2LjQ4MiwyNi40ODItMjYuNDgyaDI4Mi40ODNjNC45NDMsMCw4LjgyNy0zLjg4NCw4LjgyNy04LjgyOA0KCQkJUzMzMS41NjQsMCwzMjYuNjIxLDBINDQuMTM4QzE5Ljc3NCwwLDAsMTkuNzc0LDAsNDQuMTM4djQyMy43MjVDMCw0OTIuMjI3LDE5Ljc3NCw1MTIsNDQuMTM4LDUxMmg0MjMuNzI1DQoJCQlDNDkyLjIyNyw1MTIsNTEyLDQ5Mi4yMjcsNTEyLDQ2Ny44NjJWMTg1LjM3OUM1MTIsMTgwLjYxMiw1MDcuOTM5LDE3Ni41NTIsNTAzLjE3MywxNzYuNTUyeiIvPg0KCQk8cGF0aCBmaWxsPSIjOTk5OTk5IiBkPSJNNTExLjgyMyw3LjA2MmMwLTAuMTc2LTAuMTc3LTAuNTMtMC4xNzctMC43MDZjMC0wLjM1My0wLjE3Ni0wLjUzLTAuMzUzLTAuODgzcy0wLjM1NC0wLjUzLTAuNTMtMC44ODMNCgkJCWMtMC4xNzYtMC4xNzYtMC4xNzYtMC41My0wLjM1My0wLjcwNmMtMC43MDYtMC44ODMtMS40MTItMS43NjYtMi40NzItMi40NzJjLTAuMTc3LTAuMTc3LTAuNTI5LTAuMTc3LTAuNzA2LTAuMzUzDQoJCQljLTAuMzU0LTAuMTc3LTAuNTMtMC4zNTQtMC44ODMtMC41M2MtMC4zNTQtMC4xNzctMC41My0wLjE3Ny0wLjg4My0wLjM1M2MtMC4xNzcsMC0wLjUzLTAuMTc3LTAuNzA2LTAuMTc3DQoJCQljLTAuNTMsMC4xNzctMS4wNiwwLTEuNTksMGwwLDBIMzc5LjU4NmMtNC45NDMsMC04LjgyNywzLjg4NC04LjgyNyw4LjgyOHMzLjg4NCw4LjgyOCw4LjgyNyw4LjgyOEg0ODEuODFMMTYxLjM2OCwzMzguMDk3DQoJCQljLTMuNTMxLDMuNTMxLTMuNTMxLDkuMDA0LDAsMTIuNTM1YzEuNzY2LDEuNzY2LDQuMDYxLDIuNjQ4LDYuMTc5LDIuNjQ4YzIuMTE5LDAsNC41OS0wLjg4Myw2LjE4LTIuNjQ4TDQ5NC4zNDUsMzAuMTl2MTAyLjIyNA0KCQkJYzAsNC45NDMsMy44ODQsOC44MjcsOC44MjgsOC44MjdjNC45NDMsMCw4LjgyNy0zLjg4NCw4LjgyNy04LjgyN1Y4LjgyOEM1MTIsOC4yOTgsNTExLjgyMyw3Ljc2OCw1MTEuODIzLDcuMDYyeiIvPg0KCQk8cGF0aCBmaWxsPSIjOTk5OTk5IiBkPSJNNDQuMTM4LDM5LjcyNGMtMi40NzIsMC00LjQxNCwxLjk0Mi00LjQxNCw0LjQxNHYxMjMuNTg2YzAsMi40NzIsMS45NDIsNC40MTQsNC40MTQsNC40MTQNCgkJCWMyLjQ3MiwwLDQuNDE0LTEuOTQyLDQuNDE0LTQuNDE0VjQ4LjU1MmgxMTkuMTcyYzIuNDcyLDAsNC40MTQtMS45NDIsNC40MTQtNC40MTRjMC0yLjQ3Mi0xLjk0Mi00LjQxNC00LjQxNC00LjQxNEg0NC4xMzh6Ii8+DQoJPC9nPg0KPC9nPg0KPC9zdmc+DQo='); 375 | } 376 | } 377 | } 378 | } 379 | } 380 | } 381 | } -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/src/lib/components/ngx-image-gallery/ngx-image-gallery.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Component, 3 | OnInit, 4 | HostBinding, 5 | Input, 6 | HostListener, 7 | ElementRef, 8 | Renderer2, 9 | EventEmitter, 10 | Output, 11 | OnChanges, 12 | SimpleChanges, 13 | ViewChild, 14 | ChangeDetectorRef 15 | } from '@angular/core'; 16 | 17 | import {assign, debounce} from 'lodash'; 18 | 19 | import {GALLERY_CONF, GALLERY_IMAGE} from '../../ngx-image-gallery.conf'; 20 | import { DomSanitizer } from '@angular/platform-browser'; 21 | 22 | // key codes to react 23 | const KEY_CODES = { 24 | 37: 'LEFT', 25 | 39: 'RIGHT', 26 | 27: 'ESC' 27 | }; 28 | 29 | // default gallery configuration 30 | const DEFAULT_CONF: GALLERY_CONF = { 31 | imageBorderRadius: '3px', 32 | imageOffset: '20px', 33 | imagePointer: false, 34 | showDeleteControl: false, 35 | showCloseControl: true, 36 | showExtUrlControl: true, 37 | showImageTitle: true, 38 | showThumbnails: true, 39 | closeOnEsc: true, 40 | reactToKeyboard: true, 41 | reactToMouseWheel: true, 42 | reactToRightClick: false, 43 | thumbnailSize: 30, 44 | backdropColor: 'rgba(13,13,14,0.85)', 45 | inline: false, 46 | showArrows: true 47 | }; 48 | 49 | @Component({ 50 | selector: 'ngx-image-gallery', 51 | templateUrl: './ngx-image-gallery.component.html', 52 | styleUrls: ['./ngx-image-gallery.component.scss'] 53 | }) 54 | export class NgxImageGalleryComponent implements OnInit, OnChanges { 55 | 56 | // gallery opened memory 57 | @HostBinding('class.active') opened: boolean = false; 58 | 59 | // gallery configuration 60 | @Input() conf: GALLERY_CONF = {}; 61 | 62 | // gallery images 63 | @Input() images: GALLERY_IMAGE[] = []; 64 | 65 | // event emmiters 66 | @Output() onOpen = new EventEmitter(); 67 | @Output() onClose = new EventEmitter(); 68 | @Output() onDelete = new EventEmitter(); 69 | @Output() onImageChange = new EventEmitter(); 70 | @Output() onImageClicked = new EventEmitter(); 71 | @Output() onError = new EventEmitter(); 72 | 73 | // thumbnails container 74 | @ViewChild('thumbnails') thumbnailsElem: ElementRef; 75 | 76 | /***************************************************/ 77 | 78 | // loading animation memory 79 | loading: boolean = false; 80 | 81 | // current active image index 82 | activeImageIndex: number = null; 83 | 84 | // thumbnail margin and scroll position 85 | thumbnailMargin: string = '0px 8px'; 86 | thumbnailsScrollerLeftMargin: string = '0px'; 87 | 88 | // active image 89 | get activeImage(): GALLERY_IMAGE { 90 | return this.images[this.activeImageIndex]; 91 | } 92 | 93 | // if gallery is on : first image 94 | get onFirstImage(): boolean { 95 | return this.activeImageIndex == 0; 96 | } 97 | 98 | // if gallery is on : last image 99 | get onLastImage(): boolean { 100 | return this.activeImageIndex == (this.images.length - 1); 101 | } 102 | 103 | // get thumbnails viewport rendering parameters 104 | get thumbnailsRenderParams(): { thumbnailsInView: number, newThumbnailMargin: number, newThumbnailSize: number, thumbnailsScrollerLeftMargin: any } { 105 | let thumbnailsContainerWidth = this.thumbnailsElem.nativeElement.offsetWidth; 106 | 107 | let thumbnailMargin = 16; 108 | let thumbnailSize = thumbnailMargin + this.conf.thumbnailSize; 109 | let thumbnailsInView = Math.floor(thumbnailsContainerWidth / thumbnailSize); 110 | let extraSpaceInThumbnailsContainer = thumbnailsContainerWidth - (thumbnailsInView * thumbnailSize); 111 | let extraMargin = extraSpaceInThumbnailsContainer / thumbnailsInView; 112 | 113 | let newThumbnailMargin = thumbnailMargin + extraMargin; 114 | let newThumbnailSize = newThumbnailMargin + this.conf.thumbnailSize; 115 | 116 | let relativePositionOfActiveImageThumbnailToScroller = thumbnailsInView - (thumbnailsInView - this.activeImageIndex); 117 | let thumbnailsScrollerLeftMargin: any; 118 | 119 | if (relativePositionOfActiveImageThumbnailToScroller > thumbnailsInView - 2) { 120 | var outThumbnails = ((this.activeImageIndex + 1) - thumbnailsInView) + 1; 121 | 122 | if (this.activeImageIndex != (this.images.length - 1)) { 123 | thumbnailsScrollerLeftMargin = '-' + (newThumbnailSize * outThumbnails) + 'px'; 124 | } 125 | else { 126 | thumbnailsScrollerLeftMargin = '-' + (newThumbnailSize * (outThumbnails - 1)) + 'px'; 127 | } 128 | } else { 129 | thumbnailsScrollerLeftMargin = '0px'; 130 | } 131 | 132 | return { 133 | thumbnailsInView, 134 | newThumbnailMargin, 135 | newThumbnailSize, 136 | thumbnailsScrollerLeftMargin 137 | }; 138 | } 139 | 140 | // set gallery configuration 141 | private setGalleryConf(conf: GALLERY_CONF) { 142 | this.conf = assign(DEFAULT_CONF, conf); 143 | } 144 | 145 | // load image and return promise 146 | private loadImage(index: number): Promise { 147 | const galleryImage: GALLERY_IMAGE = this.images[index]; 148 | 149 | // check if image is cached 150 | if (galleryImage._cached) { 151 | return Promise.resolve(index); 152 | } 153 | else { 154 | return new Promise((resolve, reject) => { 155 | this.loading = true; 156 | 157 | let image = new Image(); 158 | image.src = galleryImage.url; 159 | 160 | image.onload = () => { 161 | this.loading = false; 162 | galleryImage._cached = true; 163 | resolve(index); 164 | }; 165 | 166 | image.onerror = (error) => { 167 | this.loading = false; 168 | reject(error); 169 | }; 170 | }); 171 | } 172 | } 173 | 174 | // activate image (set active image) 175 | private activateImage(imageIndex: number) { 176 | // prevent loading if already loading 177 | if (this.loading) return false; 178 | 179 | // emit event 180 | this.onImageChange.emit(imageIndex); 181 | 182 | this.loadImage(imageIndex) 183 | .then(_imageIndex => { 184 | this.activeImageIndex = _imageIndex; 185 | // Trigger change detection manually to support ChangeDetectionStrategy.OnPush 186 | this.cdRef.detectChanges(); 187 | 188 | // scroll thumbnails 189 | setTimeout(() => { 190 | this.fitThumbnails(); 191 | setTimeout(() => this.scrollThumbnails(), 300); 192 | }); 193 | }) 194 | .catch(error => { 195 | console.warn(error) 196 | this.onError.next(error); 197 | }); 198 | } 199 | 200 | // adjust thumbnail margin to perfectly fit viewport 201 | private fitThumbnails = debounce(() => { 202 | // if thumbnails not visible, return false 203 | if (this.conf.showThumbnails == false) return false; 204 | 205 | let thumbnailParams = this.thumbnailsRenderParams; 206 | this.thumbnailMargin = '0 ' + (thumbnailParams.newThumbnailMargin / 2) + 'px'; 207 | }, 300); 208 | 209 | // scroll thumbnails to perfectly position active image thumbnail in viewport 210 | private scrollThumbnails() { 211 | // if thumbnails not visible, return false 212 | if (this.conf.showThumbnails == false) return false; 213 | 214 | let thumbnailParams = this.thumbnailsRenderParams; 215 | this.thumbnailsScrollerLeftMargin = thumbnailParams.thumbnailsScrollerLeftMargin; 216 | } 217 | 218 | // debounced prev 219 | private debouncedPrev = debounce(() => this.prev(), 100, {'leading': true, 'trailing': false}); 220 | 221 | // debounced next 222 | private debouncedNext = debounce(() => this.next(), 100, {'leading': true, 'trailing': false}); 223 | 224 | /***************************************************/ 225 | 226 | constructor( 227 | public sanitizer: DomSanitizer, 228 | private galleryElem: ElementRef, 229 | private renderer: Renderer2, 230 | private cdRef: ChangeDetectorRef 231 | ) {} 232 | 233 | ngOnInit() { 234 | // create final gallery configuration 235 | this.setGalleryConf(this.conf); 236 | 237 | // apply backdrop color 238 | this.renderer.setStyle(this.galleryElem.nativeElement, 'background-color', this.conf.backdropColor); 239 | 240 | // gallery inline class and auto open 241 | if (this.conf.inline) { 242 | this.renderer.addClass(this.galleryElem.nativeElement, 'inline'); 243 | this.open(0); 244 | } 245 | } 246 | 247 | ngOnChanges(changes: SimpleChanges) { 248 | // when gallery configuration changes 249 | if (changes.conf && changes.conf.firstChange == false) { 250 | this.setGalleryConf(changes.conf.currentValue); 251 | 252 | // apply backdrop color 253 | this.renderer.setStyle(this.galleryElem.nativeElement, 'background-color', this.conf.backdropColor); 254 | 255 | // gallery inline class and auto open 256 | if ((changes.conf.previousValue.inline != true) && this.conf.inline) { 257 | this.renderer.addClass(this.galleryElem.nativeElement, 'inline'); 258 | this.open(0); 259 | } 260 | } 261 | 262 | // when gallery images changes 263 | if (changes.images && changes.images.firstChange == false) { 264 | this.images = changes.images.currentValue; 265 | 266 | if (this.images.length) { 267 | this.activateImage(0); 268 | } 269 | } 270 | 271 | } 272 | 273 | // keyboard event 274 | @HostListener('window:keydown', ['$event']) 275 | public onKeyboardInput(event: KeyboardEvent) { 276 | if (this.conf.reactToKeyboard && this.opened && !this.loading) { 277 | if (KEY_CODES[event.keyCode] == 'RIGHT') { 278 | this.next(); 279 | } 280 | else if (KEY_CODES[event.keyCode] == 'LEFT') { 281 | this.prev(); 282 | } 283 | else if ((KEY_CODES[event.keyCode] == 'ESC') && this.conf.closeOnEsc) { 284 | this.close(); 285 | } 286 | } 287 | } 288 | 289 | // window resize event 290 | @HostListener('window:resize', ['$event']) 291 | public onWindowResize(event: Event) { 292 | if (this.opened && !this.loading) { 293 | this.fitThumbnails(); 294 | setTimeout(() => this.scrollThumbnails(), 300); 295 | } 296 | } 297 | 298 | /***************************************************/ 299 | 300 | // open gallery 301 | open(index: number = 0) { 302 | if (this.images.length) { 303 | this.opened = true; 304 | 305 | // emit event 306 | this.onOpen.emit(index); 307 | 308 | // activate image at given index 309 | this.activateImage(index); 310 | } 311 | else { 312 | console.warn('No images provided to ngx-image-gallery!'); 313 | } 314 | } 315 | 316 | // close gallery 317 | close() { 318 | this.opened = false; 319 | this.activeImageIndex = 0; 320 | 321 | // emit event 322 | this.onClose.emit(); 323 | } 324 | 325 | // change prev image 326 | prev() { 327 | if (this.onFirstImage == false) { 328 | this.activateImage(this.activeImageIndex - 1); 329 | } 330 | } 331 | 332 | // change next image 333 | next() { 334 | if (this.onLastImage == false) { 335 | this.activateImage(this.activeImageIndex + 1); 336 | } 337 | } 338 | 339 | // set image (activate) 340 | setActiveImage(index: number) { 341 | this.activateImage(index); 342 | } 343 | 344 | // delete image 345 | deleteImage(index: number) { 346 | this.onDelete.emit(index); 347 | } 348 | 349 | // mouse wheel up (prev image) 350 | mouseWheelUp() { 351 | if (this.conf.reactToMouseWheel) { 352 | this.debouncedNext(); 353 | } 354 | } 355 | 356 | // mouse wheel down (next image) 357 | mouseWheelDown() { 358 | if (this.conf.reactToMouseWheel) { 359 | this.debouncedPrev(); 360 | } 361 | } 362 | 363 | // click on image 364 | clickOnImage(index: number) { 365 | this.onImageClicked.emit(index); 366 | } 367 | 368 | // right click on image 369 | rightClickOnImage(event: Event) { 370 | event.stopPropagation(); 371 | return this.conf.reactToRightClick; 372 | } 373 | 374 | } 375 | -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/src/lib/directives/click-outside.directive.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | exports.__esModule = true; 9 | var core_1 = require("@angular/core"); 10 | var ClickOutsideDirective = (function () { 11 | function ClickOutsideDirective(_elementRef) { 12 | this._elementRef = _elementRef; 13 | this.clickOutside = new core_1.EventEmitter(); 14 | } 15 | ClickOutsideDirective.prototype.onClick = function ($event, targetElement) { 16 | var isClickedInside = this._elementRef.nativeElement.contains(targetElement); 17 | if (!isClickedInside) { 18 | this.clickOutside.emit($event); 19 | } 20 | }; 21 | return ClickOutsideDirective; 22 | }()); 23 | __decorate([ 24 | core_1.Output() 25 | ], ClickOutsideDirective.prototype, "clickOutside"); 26 | __decorate([ 27 | core_1.HostListener('document:click', ['$event', '$event.target']) 28 | ], ClickOutsideDirective.prototype, "onClick"); 29 | ClickOutsideDirective = __decorate([ 30 | core_1.Directive({ 31 | selector: '[clickOutside]' 32 | }) 33 | ], ClickOutsideDirective); 34 | exports.ClickOutsideDirective = ClickOutsideDirective; 35 | -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/src/lib/directives/click-outside.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, Output, EventEmitter, HostListener } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[clickOutside]' 5 | }) 6 | export class ClickOutsideDirective { 7 | @Output() clickOutside: EventEmitter = new EventEmitter(); 8 | 9 | constructor(private _elementRef: ElementRef) {} 10 | 11 | @HostListener('document:click', ['$event', '$event.target']) 12 | public onClick($event, targetElement) { 13 | const isClickedInside = this._elementRef.nativeElement.contains(targetElement); 14 | if (!isClickedInside) { 15 | this.clickOutside.emit($event); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/src/lib/directives/mousewheel.directive.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | exports.__esModule = true; 9 | var core_1 = require("@angular/core"); 10 | var MouseWheelDirective = (function () { 11 | function MouseWheelDirective() { 12 | this.mouseWheelUp = new core_1.EventEmitter(); 13 | this.mouseWheelDown = new core_1.EventEmitter(); 14 | } 15 | MouseWheelDirective.prototype.onMouseWheelChrome = function (event) { 16 | this.mouseWheelFunc(event); 17 | }; 18 | MouseWheelDirective.prototype.onMouseWheelFirefox = function (event) { 19 | this.mouseWheelFunc(event); 20 | }; 21 | MouseWheelDirective.prototype.onMouseWheelIE = function (event) { 22 | this.mouseWheelFunc(event); 23 | }; 24 | MouseWheelDirective.prototype.mouseWheelFunc = function (event) { 25 | var event = window.event || event; // old IE support 26 | var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail))); 27 | if (delta > 0) { 28 | this.mouseWheelUp.emit(event); 29 | } 30 | else if (delta < 0) { 31 | this.mouseWheelDown.emit(event); 32 | } 33 | // for IE 34 | event.returnValue = false; 35 | // for Chrome and Firefox 36 | if (event.preventDefault) { 37 | event.preventDefault(); 38 | } 39 | }; 40 | return MouseWheelDirective; 41 | }()); 42 | __decorate([ 43 | core_1.Output() 44 | ], MouseWheelDirective.prototype, "mouseWheelUp"); 45 | __decorate([ 46 | core_1.Output() 47 | ], MouseWheelDirective.prototype, "mouseWheelDown"); 48 | __decorate([ 49 | core_1.HostListener('mousewheel', ['$event']) 50 | ], MouseWheelDirective.prototype, "onMouseWheelChrome"); 51 | __decorate([ 52 | core_1.HostListener('DOMMouseScroll', ['$event']) 53 | ], MouseWheelDirective.prototype, "onMouseWheelFirefox"); 54 | __decorate([ 55 | core_1.HostListener('onmousewheel', ['$event']) 56 | ], MouseWheelDirective.prototype, "onMouseWheelIE"); 57 | MouseWheelDirective = __decorate([ 58 | core_1.Directive({ selector: '[mouseWheel]' }) 59 | ], MouseWheelDirective); 60 | exports.MouseWheelDirective = MouseWheelDirective; 61 | -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/src/lib/directives/mousewheel.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, Output, HostListener, EventEmitter } from '@angular/core'; 2 | 3 | @Directive({ selector: '[mouseWheel]' }) 4 | export class MouseWheelDirective { 5 | @Output() mouseWheelUp = new EventEmitter(); 6 | @Output() mouseWheelDown = new EventEmitter(); 7 | 8 | @HostListener('mousewheel', ['$event']) onMouseWheelChrome(event: any) { 9 | this.mouseWheelFunc(event); 10 | } 11 | 12 | @HostListener('DOMMouseScroll', ['$event']) onMouseWheelFirefox(event: any) { 13 | this.mouseWheelFunc(event); 14 | } 15 | 16 | @HostListener('onmousewheel', ['$event']) onMouseWheelIE(event: any) { 17 | this.mouseWheelFunc(event); 18 | } 19 | 20 | mouseWheelFunc(event: any) { 21 | var event = window.event || event; // old IE support 22 | var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail))); 23 | if(delta > 0) { 24 | this.mouseWheelUp.emit(event); 25 | } else if(delta < 0) { 26 | this.mouseWheelDown.emit(event); 27 | } 28 | // for IE 29 | event.returnValue = false; 30 | // for Chrome and Firefox 31 | if(event.preventDefault) { 32 | event.preventDefault(); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/src/lib/index.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | 4 | import {NgxImageGalleryComponent} from './components/ngx-image-gallery/ngx-image-gallery.component'; 5 | import {ClickOutsideDirective} from './directives/click-outside.directive'; 6 | import {MouseWheelDirective} from './directives/mousewheel.directive'; 7 | 8 | export * from './components/ngx-image-gallery/ngx-image-gallery.component'; 9 | export * from './directives/click-outside.directive'; 10 | export * from './directives/mousewheel.directive'; 11 | export * from './ngx-image-gallery.conf'; 12 | 13 | @NgModule({ 14 | imports: [ 15 | CommonModule 16 | ], 17 | declarations: [ 18 | NgxImageGalleryComponent, 19 | MouseWheelDirective, 20 | ClickOutsideDirective 21 | ], 22 | exports: [ 23 | NgxImageGalleryComponent, 24 | MouseWheelDirective, 25 | ClickOutsideDirective 26 | ] 27 | }) 28 | export class NgxImageGalleryModule { 29 | } 30 | -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/src/lib/ngx-image-gallery.conf.ts: -------------------------------------------------------------------------------- 1 | export interface GALLERY_CONF { 2 | imageBorderRadius?: string; 3 | imageOffset?: string; 4 | imagePointer? :boolean; 5 | showDeleteControl?: boolean; 6 | showCloseControl?: boolean; 7 | showExtUrlControl?: boolean; 8 | showArrows?: boolean; 9 | showImageTitle?: boolean; 10 | showThumbnails?: boolean; 11 | closeOnEsc?: boolean; 12 | reactToKeyboard?: boolean; 13 | reactToMouseWheel?: boolean; 14 | reactToRightClick?: boolean; 15 | thumbnailSize?: number; 16 | backdropColor?: string; 17 | inline?: boolean; 18 | } 19 | 20 | export interface GALLERY_IMAGE { 21 | _cached?: boolean; 22 | url: string; 23 | thumbnailUrl?: string; 24 | altText?: string; 25 | title?: string; 26 | extUrl?: string; 27 | extUrlTarget?: string; 28 | } -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/src/public-api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Public API Surface of ngx-image-gallery 3 | */ 4 | 5 | export * from './lib/index'; 6 | -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone'; 4 | import 'zone.js/dist/zone-testing'; 5 | import { getTestBed } from '@angular/core/testing'; 6 | import { 7 | BrowserDynamicTestingModule, 8 | platformBrowserDynamicTesting 9 | } from '@angular/platform-browser-dynamic/testing'; 10 | 11 | declare const require: { 12 | context(path: string, deep?: boolean, filter?: RegExp): { 13 | keys(): string[]; 14 | (id: string): T; 15 | }; 16 | }; 17 | 18 | // First, initialize the Angular testing environment. 19 | getTestBed().initTestEnvironment( 20 | BrowserDynamicTestingModule, 21 | platformBrowserDynamicTesting() 22 | ); 23 | // Then we find all the tests. 24 | const context = require.context('./', true, /\.spec\.ts$/); 25 | // And load the modules. 26 | context.keys().map(context); 27 | -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/lib", 5 | "target": "es2015", 6 | "declaration": true, 7 | "inlineSources": true, 8 | "types": [], 9 | "lib": [ 10 | "dom", 11 | "es2018" 12 | ] 13 | }, 14 | "angularCompilerOptions": { 15 | "skipTemplateCodegen": true, 16 | "strictMetadataEmit": true, 17 | "enableResourceInlining": true 18 | }, 19 | "exclude": [ 20 | "src/test.ts", 21 | "**/*.spec.ts" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.json", 3 | "angularCompilerOptions": { 4 | "enableIvy": false 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts" 12 | ], 13 | "include": [ 14 | "**/*.spec.ts", 15 | "**/*.d.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/projects/ngx-image-gallery/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "lib", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "lib", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "lib": [ 15 | "es2018", 16 | "dom" 17 | ], 18 | "paths": { 19 | "ngx-image-gallery": [ 20 | "dist/ngx-image-gallery/ngx-image-gallery", 21 | "dist/ngx-image-gallery" 22 | ] 23 | } 24 | }, 25 | "angularCompilerOptions": { 26 | "fullTemplateTypeCheck": true, 27 | "strictInjectionParameters": true 28 | } 29 | } -------------------------------------------------------------------------------- /src/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rulesDirectory": [ 4 | "codelyzer" 5 | ], 6 | "rules": { 7 | "array-type": false, 8 | "arrow-parens": false, 9 | "deprecation": { 10 | "severity": "warning" 11 | }, 12 | "import-blacklist": [ 13 | true, 14 | "rxjs/Rx" 15 | ], 16 | "interface-name": false, 17 | "max-classes-per-file": false, 18 | "max-line-length": [ 19 | true, 20 | 140 21 | ], 22 | "member-access": false, 23 | "member-ordering": [ 24 | true, 25 | { 26 | "order": [ 27 | "static-field", 28 | "instance-field", 29 | "static-method", 30 | "instance-method" 31 | ] 32 | } 33 | ], 34 | "no-consecutive-blank-lines": false, 35 | "no-console": [ 36 | true, 37 | "debug", 38 | "info", 39 | "time", 40 | "timeEnd", 41 | "trace" 42 | ], 43 | "no-empty": false, 44 | "no-inferrable-types": [ 45 | true, 46 | "ignore-params" 47 | ], 48 | "no-non-null-assertion": true, 49 | "no-redundant-jsdoc": true, 50 | "no-switch-case-fall-through": true, 51 | "no-var-requires": false, 52 | "object-literal-key-quotes": [ 53 | true, 54 | "as-needed" 55 | ], 56 | "object-literal-sort-keys": false, 57 | "ordered-imports": false, 58 | "quotemark": [ 59 | true, 60 | "single" 61 | ], 62 | "trailing-comma": false, 63 | "component-class-suffix": true, 64 | "contextual-lifecycle": true, 65 | "directive-class-suffix": true, 66 | "no-conflicting-lifecycle": true, 67 | "no-host-metadata-property": true, 68 | "no-input-rename": true, 69 | "no-inputs-metadata-property": true, 70 | "no-output-native": true, 71 | "no-output-on-prefix": true, 72 | "no-output-rename": true, 73 | "no-outputs-metadata-property": true, 74 | "template-banana-in-box": true, 75 | "template-no-negated-async": true, 76 | "use-lifecycle-interface": true, 77 | "use-pipe-transform-interface": true 78 | } 79 | } 80 | --------------------------------------------------------------------------------