1

I have a ng-bootstrap Carousel in my Angular project and I would like to change a few things but am at a loss of how to go about it.

First, I would like to have a fade effect when the slide changes, at the moment the next image just appears.

Secondly, I want to have my own arrows and slide indicator or change the style! I have attempted to do that via CSS but none of my code seems to get accepted.

Below my slideshow-component:

 images = [1, 2, 3, 4, 5, 6, 7].map(() => `https://picsum.photos/900/500?random&t=${Math.random()}`); paused = false; unpauseOnArrow = false; pauseOnIndicator = false; pauseOnHover = true; @ViewChild('carousel', {static : true}) carousel: NgbCarousel; togglePaused() { if (this.paused) { this.carousel.cycle(); } else { this.carousel.pause(); } this.paused = !this.paused; } onSlide(slideEvent: NgbSlideEvent) { if (this.unpauseOnArrow && slideEvent.paused && (slideEvent.source === NgbSlideEventSource.ARROW_LEFT || slideEvent.source === NgbSlideEventSource.ARROW_RIGHT)) { this.togglePaused(); } if (this.pauseOnIndicator && !slideEvent.paused && slideEvent.source === NgbSlideEventSource.INDICATOR) { this.togglePaused(); } }

slideshow-component html

<ngb-carousel #carousel interval="3000" [pauseOnHover]="pauseOnHover" (slide)="onSlide($event)"> <ng-template ngbSlide *ngFor="let img of images; index as i"> <div class="picsum-img-wrapper"> <img [src]="img" alt="My image {{i + 1}} description"> </div> </ng-template> </ngb-carousel>

slideshow-component css

.picsum-img-wrapper {	img {	width: 100vw;	height: 100vh;	max-width: 100%;	display: block;	margin: 0;	} } .carousel-indicators > li {	visibility: hidden; box-sizing: content-box; flex: 0 1 auto; width: 30px; height: 30px; border-radius: 20px; margin-right: 3px; margin-left: 3px; text-indent: -999px; cursor: pointer; background-color: #fff; background-clip: padding-box; border-top: 10px solid transparent; border-bottom: 10px solid transparent; opacity: .5; transition: opacity .6s ease; } a.carousel-control-prev, a.carousel-control-next {	span {	display: none;	} }

1 Answer 1

7

you need use encapsulation:ViewEncapsulation.None (*)

This allow you override the css. In ngb-carousel, the class that contrl the items are .carousel-item and carousel-item.active. carousel-item has display:none and carouse-item.active has display:block, so you need change by opacity:0 and opacity:1. Use the own .css to make the transition. Some like (see stackblitz

@Component({selector: 'ngbd-carousel-basic', templateUrl: './carousel-basic.html', encapsulation: ViewEncapsulation.None, styles:[` .carousel-item { display:block; opacity:0; transition: opacity 2s; } .carousel-item.active { display:block; opacity:1; transition: opacity 2s; } .carousel-control-next-icon { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 24 24'%3e%3cpath d='M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm-1.568 18.005l-1.414-1.415 4.574-4.59-4.574-4.579 1.414-1.416 5.988 5.995-5.988 6.005z'/%3e%3c/svg%3e"); } .carousel-control-prev-icon { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 24 24'%3e%3cpath d='M0 12c0 6.627 5.373 12 12 12s12-5.373 12-12-5.373-12-12-12-12 5.373-12 12zm7.58 0l5.988-5.995 1.414 1.416-4.574 4.579 4.574 4.59-1.414 1.416-5.988-6.006z'/%3e%3c/svg%3e"); } `] } ) 

Updated If you want to do the animation at "Angular style", you need override the class too

styles:[` .carousel-item { display:block; } .carousel-caption { display:block } 

And create an animation like

animations: [ trigger('simpleFadeAnimation', [ state('false', style({opacity: 0})), transition('*=>false', [ style({opacity: 1}), animate(600 ) ]), transition('false=>*', animate(600, style({opacity: 1}))) ]) ] 

The .html it's look like to

<ngb-carousel #carousel *ngIf="images" interval=0 wrap="true" > <ng-template ngbSlide id="id1"> <div class="picsum-img-wrapper" [@simpleFadeAnimation]="carousel &&carousel.activeId=='id1'"> <img [src]="images[0]" width="100%" alt="Random first slide"> <div class="carousel-caption" > <h3>First slide label</h3> <p>Nulla vitae elit libero, a pharetra augue mollis interdum.</p> </div> </div> </ng-template> <ng-template ngbSlide id="id2"> <div class="picsum-img-wrapper" [@simpleFadeAnimation]="carousel &&carousel.activeId=='id2'"> <img [src]="images[1]" width="100%" alt="Random second slide"> <div class="carousel-caption" > <h3>Second slide label</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> </div> </div> </ng-template> <ng-template ngbSlide id="id3"> <div class="picsum-img-wrapper" [@simpleFadeAnimation]="carousel &&carousel.activeId=='id3'"> <img [src]="images[2]" width="100%" alt="Random third slide"> <div class="carousel-caption" > <h3>Third slide label</h3> <p>Praesent commodo cursus magna, vel scelerisque nisl consectetur.</p> </div> </div> </ng-template> </ngb-carousel> 

see the new stackblitz

Updated 2 if we want the slides go from left to right we can use an animtion like

 animations: [ trigger('simpleTranslation', [ state('outright', style({ transform: `translateX(100%)` })), state('outleft', style({ transform: `translateX(-100%)` })), state('inleft', style({ transform: `translateX(0)` })), state('inright', style({ transform: `translateX(0)` })), transition('*=>inleft',[ style({transform:`translateX(-100%)`}), animate('260ms ease-in') ]), transition('*=>inright',[ style({transform:`translateX(100%)`}), animate('260ms ease-in') ]), transition('*=>outright', [ animate('260ms ease-in', style({ transform: `translateX(-100%)` })) ]), transition('*=>outleft', [ animate('260ms ease-in',style({ transform: `translateX(100%)` })) ]), ]) ] 

where we need get the Slides in view children and use the slide event

 @ViewChildren(NgbSlide) slides: QueryList<NgbSlide> slideControl: any[] = [] onSlide(event) { this.slides.forEach((x, index) => { if (x.id == event.current) { this.slideControl[index] = 'in' + event.direction } if (x.id == event.prev) { this.slideControl[index] = 'out' + event.direction } }) } 

the .html like

<ngb-carousel #carousel *ngIf="images" interval=0 wrap="true" (slide)=onSlide($event)> <ng-template ngbSlide id="id1"> <div class="picsum-img-wrapper" [@simpleTranslation]="slideControl[0]"> <img [src]="images[0]" alt="Random first slide"> <div class="carousel-caption" > <h3>First slide label</h3> <p>Nulla vitae elit libero, a pharetra augue mollis interdum.</p> </div> </div> </ng-template> <ng-template ngbSlide id="id2"> <div class="picsum-img-wrapper" [@simpleTranslation]="slideControl[1]"> <img [src]="images[1]" alt="Random second slide"> <div class="carousel-caption" > <h3>Second slide label</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> </div> </div> </ng-template> ... </ngb-carousel> 

See another stackblitz

(*)ViewEncapsultaion.None make that the .css in your .component was for all the app. So use it carefully, if e.g. you write in your component a css h1{color:red} all yours h1 in your application becomes "red"

Sign up to request clarification or add additional context in comments.

7 Comments

Slide effect works well, I think only problem is that it doesn't change without clicking on arrows.
@foo-baar, it's not about slide effect, if you click inside the carousel, the keyboard work (exactly a normal ngb-carousel). You always can inject Renderer2 and listen keydown.arrowleft and keydown.arrowright: e.g. this.renderer.listen(document, 'keydown.arrowleft', ()=>{ this.carousel.prev() }) or use some like netbasal.com/… to control the keyboard
Thanks for replying, what I meant was that auto slide in at a fixed interval doesn't work in the above implementation,
@foo-baar, in the stackblitz, in the .html I wrote interval=0, replace by, e.g. interval=3000, must be work
Last question: which one do you prefer ng-bootstrap or mdbootstrap ?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.