1- import { Directive , ElementRef , AfterViewInit , Input } from '@angular/core' ;
2- import { AnimationCurve } from "ui/enums" ;
1+ import { AfterViewInit , Directive , ElementRef , EventEmitter , Input , Output } from '@angular/core' ;
32import { Image } from "ui/image" ;
43import { StackLayout } from "ui/layouts/stack-layout" ;
54import { GridLayout , ItemSpec } from "ui/layouts/grid-layout" ;
6- import { GridUnitType } from "ui/layouts/grid-layout" ;
7- import { HorizontalAlignment } from "ui/enums" ;
85import { Label } from "ui/label" ;
9- import { GestureTypes } from "ui/gestures" ;
6+ import { GestureTypes , SwipeGestureEventData } from "ui/gestures" ;
107import { View } from "ui/core/view" ;
11- import { Visibility } from "ui/enums" ;
12- import { fromFile } from "image-source" ;
13- import { fromResource } from "image-source" ;
8+ import { fromFile , fromResource } from "image-source" ;
149
1510@Directive ( { selector : '[carousel]' } )
1611export class CarouselDirective implements AfterViewInit {
1712
13+ private static TRANSPARENT : string = "#FFFFFF" ;
14+
1815 private static animationSpeedDefault : number = 400 ; // in ms
1916 private static autoPlaySpeedDefault : number = 0 ; // in ms
2017
@@ -27,18 +24,23 @@ export class CarouselDirective implements AfterViewInit {
2724
2825 // Private control attributes
2926 private direction : CarouselDirections = null ;
30- private currentImage : number = 0 ;
3127 private movingImages : boolean = false ;
32- private indexMoveLeft : number = null ;
33- private indexMoveRight : number = null ;
34- private indexMoveCenter : number = null ;
28+
29+ // My pointers
30+ private currentImage : number = 0 ;
31+ private nextImage : number = null ;
32+ private nextNextImage : number = null ;
3533
3634 // Options
3735 @Input ( ) carousel : any ;
3836 @Input ( ) carouselSpeed : number ; // autoplay speed (ms)
3937 @Input ( ) carouselArrows : string ; // arrows type
38+ @Input ( ) arrowsEnabled : boolean = false ; // enable arrows [default to false]
4039 @Input ( ) carouselLabelOverlay : boolean ; // title over image (bool)
4140 @Input ( ) carouselAnimationSpeed : number ; // animation speed
41+ @Input ( ) currentElementHiglhtColor : string ;
42+
43+ @Output ( ) selectedImageChange : EventEmitter < string > = new EventEmitter < string > ( ) ;
4244
4345 constructor ( private elem : ElementRef ) {
4446 this . container = elem . nativeElement ;
@@ -49,8 +51,12 @@ export class CarouselDirective implements AfterViewInit {
4951 this . initContainer ( ) ;
5052 this . initImagesLayout ( ) ;
5153 this . initSlides ( ) ;
52- this . initControls ( ) ;
54+ // Prefer swipe over arrows tap
55+ if ( this . arrowsEnabled === true ) {
56+ this . initControls ( ) ;
57+ }
5358 this . initAutoPlay ( ) ;
59+ console . log ( `${ this . currentElementHiglhtColor } ` )
5460 }
5561
5662 /**
@@ -100,10 +106,8 @@ export class CarouselDirective implements AfterViewInit {
100106 * Init carousel layout
101107 */
102108 private initContainer ( ) {
103- this . container . horizontalAlignment = "center " ;
109+ this . container . horizontalAlignment = "left " ;
104110 this . container . addRow ( new ItemSpec ( 1 , "auto" ) ) ;
105- this . container . addColumn ( new ItemSpec ( 1 , "star" ) ) ;
106- this . container . addColumn ( new ItemSpec ( 1 , "star" ) ) ;
107111 }
108112
109113 /**
@@ -112,10 +116,30 @@ export class CarouselDirective implements AfterViewInit {
112116 private initImagesLayout ( ) {
113117 this . totalItems = this . carousel . length ;
114118 this . carouselSlides = new GridLayout ( ) ;
115- GridLayout . setColumnSpan ( this . carouselSlides , 2 ) ;
119+ GridLayout . setColumnSpan ( this . carouselSlides , 3 ) ;
120+ this . carouselSlides . addColumn ( new ItemSpec ( 1 , 'auto' ) ) ;
121+ this . carouselSlides . addColumn ( new ItemSpec ( 1 , 'auto' ) ) ;
122+ this . carouselSlides . addColumn ( new ItemSpec ( 1 , 'auto' ) ) ;
116123 this . container . addChild ( this . carouselSlides ) ;
117124 }
118125
126+ private initVisibility ( index : number ) {
127+ return index === 0 || index === 1 || index === 2 ? "visible" : "collapse" ;
128+ }
129+
130+ private getInitColPos ( index : number ) {
131+ switch ( index ) {
132+ case 0 :
133+ return 0 ;
134+ case 1 :
135+ return 1 ;
136+ case 2 :
137+ return 2 ; // could be any value between 0-2 since would be collapse
138+
139+ }
140+ }
141+
142+
119143 /**
120144 * Init carousel sliders provided in "carousel" directive attribute
121145 */
@@ -124,23 +148,59 @@ export class CarouselDirective implements AfterViewInit {
124148
125149 let gridLayout = new GridLayout ( ) ;
126150 gridLayout . addRow ( new ItemSpec ( 1 , "auto" ) ) ;
127- gridLayout . visibility = i == 0 ? "visible" : "collapse" ;
151+ gridLayout . visibility = this . initVisibility ( i ) ;
152+
153+ if ( i === 0 ) {
154+ gridLayout . backgroundColor = this . currentElementHiglhtColor ;
155+ }
128156
157+ let image : Image ;
129158 if ( slide . url ) {
130- let image : Image = CarouselDirective . generateImageSliderFromUrl ( slide . url ) ;
159+ image = CarouselDirective . generateImageSliderFromUrl ( slide . url ) ;
160+ image . on ( GestureTypes . tap , ( ) => {
161+ this . selectedImageChange . emit ( slide . title ) ;
162+ } ) ;
163+ image . on ( GestureTypes . swipe , ( args : SwipeGestureEventData ) => {
164+ if ( args . direction === 1 ) {
165+ this . swipe ( CarouselDirections . DIRECTION_LEFT ) ;
166+ } else if ( args . direction === 2 ) {
167+ this . swipe ( CarouselDirections . DIRECTION_RIGHT ) ;
168+ }
169+ } ) ;
131170 gridLayout . addChild ( image ) ;
132171 }
133172
134173 if ( slide . file && slide . file . indexOf ( 'res://' ) !== 0 ) {
135- let image : Image = CarouselDirective . generateImageSliderFromFile ( slide . file ) ;
174+ image = CarouselDirective . generateImageSliderFromFile ( slide . file ) ;
175+ image . on ( GestureTypes . tap , ( ) => {
176+ this . selectedImageChange . emit ( slide . title ) ;
177+ } ) ;
178+ image . on ( GestureTypes . swipe , ( args : SwipeGestureEventData ) => {
179+ if ( args . direction === 1 ) {
180+ this . swipe ( CarouselDirections . DIRECTION_LEFT ) ;
181+ } else if ( args . direction === 2 ) {
182+ this . swipe ( CarouselDirections . DIRECTION_RIGHT ) ;
183+ }
184+ } ) ;
136185 gridLayout . addChild ( image ) ;
137186 }
138187
139188 if ( slide . file && slide . file . indexOf ( 'res://' ) === 0 ) {
140- let image : Image = CarouselDirective . generateImageSliderFromResource ( slide . file ) ;
189+ image = CarouselDirective . generateImageSliderFromResource ( slide . file ) ;
190+ image . on ( GestureTypes . tap , ( ) => {
191+ this . selectedImageChange . emit ( slide . title ) ;
192+ } ) ;
193+ image . on ( GestureTypes . swipe , ( args : SwipeGestureEventData ) => {
194+ if ( args . direction === 1 ) {
195+ this . swipe ( CarouselDirections . DIRECTION_LEFT ) ;
196+ } else if ( args . direction === 2 ) {
197+ this . swipe ( CarouselDirections . DIRECTION_RIGHT ) ;
198+ }
199+ } ) ;
141200 gridLayout . addChild ( image ) ;
142201 }
143202
203+
144204 if ( slide . title ) {
145205 let title : Label = CarouselDirective . generateTitleSlider ( slide . title ) ;
146206 if ( this . carouselLabelOverlay ) {
@@ -149,7 +209,11 @@ export class CarouselDirective implements AfterViewInit {
149209 }
150210 gridLayout . addChild ( title ) ;
151211 }
212+
152213 this . carouselSlides . addChild ( gridLayout ) ;
214+ if ( gridLayout . visibility === 'visible' ) {
215+ GridLayout . setColumn ( gridLayout , this . getInitColPos ( i ) ) ;
216+ }
153217 } ) ;
154218 }
155219
@@ -252,6 +316,7 @@ export class CarouselDirective implements AfterViewInit {
252316 private initAutoPlay ( ) {
253317 if ( this . carouselSpeed && CarouselDirective . isNumeric ( this . carouselSpeed ) ) {
254318 clearInterval ( this . autoPlayIntervalId ) ;
319+ // @ts -ignore
255320 this . autoPlayIntervalId = setInterval ( ( ) => {
256321 this . swipe ( CarouselDirections . DIRECTION_RIGHT ) ;
257322 } , this . carouselSpeed + this . carouselAnimationSpeed ) ;
@@ -265,6 +330,7 @@ export class CarouselDirective implements AfterViewInit {
265330 if ( this . autoPlayIntervalId ) {
266331 clearTimeout ( this . autoPlayTimeoutId ) ;
267332 clearInterval ( this . autoPlayIntervalId ) ;
333+ // @ts -ignore
268334 this . autoPlayTimeoutId = setTimeout ( ( ) => {
269335 this . swipe ( CarouselDirections . DIRECTION_RIGHT ) ;
270336 this . initAutoPlay ( ) ;
@@ -305,81 +371,29 @@ export class CarouselDirective implements AfterViewInit {
305371
306372 // Get element width + image visibility
307373 let elementWidth = this . elem . nativeElement . getActualSize ( ) . width ;
308- view . visibility = [ this . indexMoveCenter , this . indexMoveLeft , this . indexMoveRight ] . indexOf ( i ) > - 1 ? "visible" : "collapse" ;
374+ view . visibility = [ this . currentImage , this . nextImage , this . nextNextImage ] . indexOf ( i ) > - 1 ? "visible" : "collapse" ;
309375
310- // Perfrom animation
311- this . checkCL ( view , i , elementWidth ) ;
312- this . checkCR ( view , i , elementWidth ) ;
313- this . checkRC ( view , i , elementWidth ) ;
314- this . checkLC ( view , i , elementWidth ) ;
315- }
316- }
317-
318- /**
319- * Move image center -> left
320- * @param view
321- * @param index
322- * @param elementWidth
323- */
324- private checkCL ( view : View , index : number , elementWidth : number ) {
325- if ( this . indexMoveLeft == index ) {
326- view . translateX = 0 ;
327- view . animate ( {
328- translate : { x : elementWidth , y : 0 } ,
329- duration : this . carouselAnimationSpeed ,
330- curve : AnimationCurve . easeIn
331- } ) ;
332- }
333- }
334-
335- /**
336- * Move image right -> center
337- * @param view
338- * @param index
339- * @param elementWidth
340- */
341- private checkRC ( view : View , index : number , elementWidth : number ) {
342- if ( this . indexMoveCenter == index && this . direction == CarouselDirections . DIRECTION_LEFT ) {
343- view . translateX = - elementWidth ;
344- view . animate ( {
345- translate : { x : 0 , y : 0 } ,
346- duration : this . carouselAnimationSpeed ,
347- curve : AnimationCurve . easeOut
348- } ) ;
349- }
350- }
351-
352- /**
353- * Move image center -> right
354- * @param view
355- * @param index
356- * @param elementWidth
357- */
358- private checkCR ( view : View , index : number , elementWidth : number ) {
359- if ( this . indexMoveRight == index ) {
360- view . translateX = 0 ;
361- view . animate ( {
362- translate : { x : - elementWidth , y : 0 } ,
363- duration : this . carouselAnimationSpeed ,
364- curve : AnimationCurve . easeIn
365- } ) ;
376+ // Perfrom translation
377+ if ( view . visibility === 'visible' ) {
378+ this . applySwipe ( view , i , elementWidth ) ;
379+ }
366380 }
367381 }
368382
369- /**
370- * Move image left -> center
371- * @param view
372- * @param index
373- * @param elementWidth
374- */
375- private checkLC ( view : View , index : number , elementWidth : number ) {
376- if ( this . indexMoveCenter == index && this . direction == CarouselDirections . DIRECTION_RIGHT ) {
377- view . translateX = elementWidth ;
378- view . animate ( {
379- translate : { x : 0 , y : 0 } ,
380- duration : this . carouselAnimationSpeed ,
381- curve : AnimationCurve . easeOut
382- } ) ;
383+ private applySwipe ( view : View , index : number , elementWidth : number ) {
384+ switch ( index ) {
385+ case this . currentImage :
386+ view . backgroundColor = this . currentElementHiglhtColor ;
387+ GridLayout . setColumn ( view , 0 ) ;
388+ break ;
389+ case this . nextImage :
390+ view . backgroundColor = CarouselDirective . TRANSPARENT ;
391+ GridLayout . setColumn ( view , 1 ) ;
392+ break ;
393+ case this . nextNextImage :
394+ view . backgroundColor = CarouselDirective . TRANSPARENT ;
395+ GridLayout . setColumn ( view , 2 ) ;
396+ break ;
383397 }
384398 }
385399
@@ -391,16 +405,16 @@ export class CarouselDirective implements AfterViewInit {
391405
392406 // right to left
393407 case CarouselDirections . DIRECTION_LEFT :
394- this . indexMoveLeft = this . currentImage ;
395- this . currentImage = ( ( this . currentImage == 0 ? this . totalItems : this . currentImage ) - 1 ) % this . totalItems ;
396- this . indexMoveCenter = this . currentImage ;
408+ this . currentImage = ( ( this . currentImage === 0 ? this . totalItems : this . currentImage ) - 1 ) % this . totalItems ;
409+ this . nextImage = ( ( this . currentImage = == 0 ? this . totalItems : this . currentImage ) - 1 ) % this . totalItems ;
410+ this . nextNextImage = ( ( this . nextImage === 0 ? this . totalItems : this . nextImage ) - 1 ) % this . totalItems ;
397411 break ;
398412
399413 // left to right
400414 case CarouselDirections . DIRECTION_RIGHT :
401- this . indexMoveRight = this . currentImage ;
402- this . currentImage = ( this . currentImage + 1 ) % this . totalItems ;
403- this . indexMoveCenter = this . currentImage ;
415+ this . currentImage = ( ( this . currentImage === 0 ? this . totalItems : this . currentImage ) + 1 ) % this . totalItems ;
416+ this . nextImage = ( this . currentImage + 1 ) % this . totalItems ;
417+ this . nextNextImage = ( this . nextImage + 1 ) % this . totalItems ;
404418 break ;
405419 }
406420 }
@@ -409,9 +423,8 @@ export class CarouselDirective implements AfterViewInit {
409423 * Reset values after animation
410424 */
411425 private resetAnimationValues ( ) {
412- this . indexMoveLeft = null ;
413- this . indexMoveRight = null ;
414- this . indexMoveCenter = null ;
426+ this . nextImage = null ;
427+ this . nextNextImage = null ;
415428 this . movingImages = false ;
416429 }
417430
0 commit comments