Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
676 views
in Technique[技术] by (71.8m points)

html - Customise NG Bootstrap carousel in Angular

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();
    }
  }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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"


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...