Customise Ng Bootstrap Carousel in Angular

Customise NG Bootstrap carousel in Angular

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"

How to change bootstrap carousel items Angular

There is an Angular library for working with Bootstrap, NG-Bootstrap. I think you would be better off using that than trying to manipulate the DOM directly.

They have support for the Bootstrap Carousel as well, found here: https://ng-bootstrap.github.io/#/components/carousel/examples

If you really insisted on doing the basics of this yourself, you need a way to mange the "active" css class on the carousel items.

Something like this could get you going in the right direction, but the Bootstrap carousel has more features other than just showing/hiding a particular slide:

Your component.ts file

currentIndex: number = 1;
CarouselChange(index) {
this.currentIndex = index;
}

Your template

<!-- Carousel -->
<div *ngIf="collection === 'Boudoir'" class="card img-row ">
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item" [class.active]="currentIndex === 1">
<img class="d-block w-100" src="" alt="First slide">
</div>
<div class="carousel-item" [class.active]="currentIndex === 2">
<img class="d-block w-100" src="" alt="Second slide">
</div>
<div class="carousel-item" [class.active]="currentIndex === 3">
<img class="d-block w-100" src="" alt="Third slide">
</div>
<div class="carousel-item" [class.active]="currentIndex === 4">
<img class="d-block w-80" src="" alt="Fourth slide">
</div>
</div>
</div>
</div>

<div *ngIf="collection === 'Boudoir'"class="img-row picsRow">
<li class="img-column pics">
<img class="gallery" src="" (click)="CarouselChange(1)">
<img class="gallery" src="" (click)="CarouselChange(2)">
<img class="gallery" src="" (click)="CarouselChange(3)">
<img class="gallery" src="" (click)="CarouselChange(4)">
</li>
</div>

To make it better, you should probably loop through in your template so you can dynamically add any number of items, or use the NG-Bootstrap library

customize ng-bootstrap carousel?

Let consider the 3 things you want to do in turn...

1. Animate so slides come from the bottom

For this, you can add the following CSS to your component that houses the ngb-carousel:

::ng-deep .carousel-item {
display: block !important;
position: absolute;
transform: translateY(100%);
opacity: 0;
transition:all 1s;
}

::ng-deep .carousel-item.active {
position: relative;
transform: translateY(0);
opacity: 1;
top: 0;
}

You should be able to tweak the CSS until you get the exact animation you want.

Warning: Angular is planning to deprecate /deep/, >>>, and ::ng-deep, however you should be able to use ::ng-deep for the time being:

The shadow-piercing descendant combinator is deprecated and support is being removed from major browsers and tools. As such we plan to drop support in Angular (for all 3 of /deep/, >>> and ::ng-deep). Until then ::ng-deep should be preferred for a broader compatibility with the tools.

source: https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep

2. Disable automatic changing of slides

Set the interval property of ngb-carousel to false - this is usually a numeric value (number of milliseconds to keep each slide on show), but setting it to false will disable the automatic slideshow.

<ngb-carousel *ngIf="images" [interval]="false" #carousel></ngb-carousel>

3. Change slide on mouse scroll

Add the following @HostListener in your component. This listens for the mouse scroll event and will execute the code within the scroll() function when it detects the event. The code below load the previous slide if you scroll down, and the next slide if you scroll up. Change event.wheelDelta < 0 to event.wheelDelta > 0 if you want it the other way round.

@HostListener('mousewheel', ['$event'])
scroll() {
if (event.wheelDelta < 0) {
this.carousel.prev();
} else {
this.carousel.next();
}
}

To get this to work, you will need to declare the ngb-carousel as a variable so you can access it in the Typescript in order to call next() and prev():

HTML

<ngb-carousel *ngIf="images" [interval]="false" #carousel>

Typescript

@ViewChild('carousel')
carousel: any;

Please see this StackBlitz for a working demo.

Custom Ng-Bootstrap Carousel, display image and description fields

the 2 points from your question:

  • I was wondering if there was a way to maybe put it in a separate file and pull the information from there?

    • Yes, you can have this information in a json file on your server... or better in a database somewhere; in my example i placed the file in a json file.
  • I need to change the text that is on the left column dynamically along with the image. For every slide there should be a date and a short description displayed

    • You can have an object instead of array of images, here you can have any number of fields that you actually need in your front end

relevant JSON file:

{ "imgArray": [
{"img": "https://picsum.photos/id/501/900/500", "heading" :"first", "description":"first heading's description"},
{"img": "https://picsum.photos/id/502/900/500", "heading" :"h2", "description":"second heading's description"},
{"img": "https://picsum.photos/id/503/900/500", "heading" :"h3", "description":"third heading's description"},
{"img": "https://picsum.photos/id/504/900/500", "heading" :"h4", "description":"fourth heading's description"},
{"img": "https://picsum.photos/id/505/900/500", "heading" :"h5", "description":"fifth heading's description"},
{"img": "https://picsum.photos/id/506/900/500", "heading" :"h6", "description":"sixth heading's description"},
{"img": "https://picsum.photos/id/507/900/500", "heading" :"h7", "description":"seventh heading's description"}
]
}

relevant HTML:

<ngb-carousel *ngIf="images">
<ng-template ngbSlide *ngFor="let slide of images; index as i">
<div class='row'>
<div class='col-lg-6 col-md-6 col-sm-6 col-6 '>
<div class="description_date">
<h1>{{slide.heading}}</h1>
</div>
<div class="description_text">
{{slide.description}}
</div>
</div>
<div class='col-lg-6 col-md-6 col-sm-6 col-6'>
<div class="gallery_img">
<figure>
<img [src]="slide.img" alt="Random first slide">
</figure>
</div>
</div>
</div>
</ng-template>
</ngb-carousel>

relevant TS:

import { Component } from '@angular/core';
import { NgbCarouselConfig } from '@ng-bootstrap/ng-bootstrap';
import * as dataJSON from './data.json';

@Component({
selector: 'ngbd-carousel-config',
templateUrl: './carousel-config.html',
providers: [NgbCarouselConfig] // add NgbCarouselConfig to the component providers
,styles: [`
.img-fluid{ min-width:100%}
.row{background:lightgray;}
.description_date, .description_text { padding:5%; }
`]
})
export class NgbdCarouselConfig {
images:any[] = []
readJSON = dataJSON;

constructor(config: NgbCarouselConfig) {
// customize default values of carousels used by this component tree
config.interval = 10000;
config.wrap = false;
config.keyboard = true;
config.pauseOnHover = false;

this.images = this.readJSON.default.imgArray;
}
}

working stackblitz here

Angular/ng-bootstrap - Carousel Arrow Customization

Try to make your CSS including important because of NGB carousel CSS override this CSS that you are including into your component.css file as below

ngb-carousel {
width: 900px;
}

.carousel-control-prev-icon{
background-image: url('https://apufpel.com.br/assets/img/seta_prim.png') !important;
}
.carousel-control-next-icon{
background-image: url('https://apufpel.com.br/assets/img/seta_ult.png')!important;
}

Hope this will help!!

How to replace images with divs in ng-bootstrap carousel?

You can just remove the image things and use the div content, for example

<ngb-carousel *ngIf="showCarousel" #carousel [interval]="5000">
<ng-template ngbSlide>
<div style="background-color: black; height: 200px">
<h1>Graph 1</h1>
</div>
</ng-template>
<ng-template ngbSlide>
<div style="background-color: black; height: 200px">
<h1>Graph 2</h1>
</div>
</ng-template>
</ngb-carousel>

How modify CSS of ng-bootstrap carousel using Angular 2

This question has more to do with how styles encapsulation work in Angular rather than something specific to ng-bootstrap, but the short answer is that in the default style encapsulation (from https://angular.io/docs/ts/latest/guide/component-styles.html):

Component styles normally apply only to the HTML in the component's
own template

Since ngb-carousel is not part of the component HTML (it is a different component altogether) you have to force styles to propagate down the components structure:

Use the /deep/ selector to force a style down through the child
component tree into all the child component views. The /deep/ selector
works to any depth of nested components, and it applies to both the
view children and content children of the component

Translating this to your particular problem would mean that you should write:

  styles: [`
/deep/ .carousel-item.active {
border: solid 0.3em;
border-color: red;
}
`]

Here is a live example in a plunker: http://plnkr.co/edit/7J3CItUtSua1zJ7GG1xH?p=preview



Related Topics



Leave a reply



Submit