Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bootstrap Slides lagging while using multi item carousel using angular 6

My issue is I am using Angular 6, Bootstrap v4 and jQuery for the multi-item carousel. If I have data like [1,2,3,4,5,6] there on the carousel it has to show [1,2,3]. After pressing the next it has to show [4,5,6].

Up to this part I achieved, I am facing issues. Only the first active card is moving and there is a lagging also and the previous and next button are not visible. Please check once Stackblitz file you will understand the issue

Here is my work in Stackblitz

https://stackblitz.com/edit/angular-jvr6dh

HTML code

<div class="container">
  <div id="dataInfo">
      <h2>Information</h2>
      <div id="myCarousel" class="carousel slide" data-ride="carousel">
          <div class="carousel-inner row w-100 mx-auto">
            <div class="carousel-item col-md-4 active">
              <div class="card">
                <img class="card-img-top img-fluid" src="https://images.freeimages.com/images/large-previews/85a/daisy-s-1375598.jpg"  width="100" height="100" alt="Card image cap">
                <div class="card-body">
                  <h4 class="card-title">Card 1</h4>
                  <p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
                  <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
                </div>
              </div>
            </div>
            <div class="carousel-item col-md-4">
              <div class="card">

                <img class="card-img-top img-fluid" src="https://images.freeimages.com/images/large-previews/85a/daisy-s-1375598.jpg"  width="100" height="100" alt="Card image cap"><div class="card-body">
                  <h4 class="card-title">Card 2</h4>
                  <p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
                  <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
                </div>
              </div>
            </div>
            <div class="carousel-item col-md-4">
              <div class="card">

                <img class="card-img-top img-fluid" src="https://images.freeimages.com/images/large-previews/85a/daisy-s-1375598.jpg"  width="100" height="100" alt="Card image cap"><div class="card-body">
                  <h4 class="card-title">Card 3</h4>
                  <p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
                  <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
                </div>
              </div>
            </div>
            <div class="carousel-item col-md-4">
              <div class="card">

                <img class="card-img-top img-fluid" src="https://images.freeimages.com/images/large-previews/85a/daisy-s-1375598.jpg"  width="100" height="100" alt="Card image cap"><div class="card-body">
                  <h4 class="card-title">Card 4</h4>
                  <p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
                  <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
                </div>
              </div>
            </div>
            <div class="carousel-item col-md-4">
              <div class="card">

                <img class="card-img-top img-fluid" src="https://images.freeimages.com/images/large-previews/85a/daisy-s-1375598.jpg"  width="100" height="100" alt="Card image cap"> <div class="card-body">
                  <h4 class="card-title">Card 5</h4>
                  <p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
                  <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
                </div>
              </div>
            </div>
            <div class="carousel-item col-md-4">
              <div class="card">

                <img class="card-img-top img-fluid" src="https://images.freeimages.com/images/large-previews/85a/daisy-s-1375598.jpg"  width="100" height="100" alt="Card image cap"><div class="card-body">
                  <h4 class="card-title">Card 6</h4>
                  <p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
                  <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
                </div>
              </div>
            </div>
            <div class="carousel-item col-md-4">
              <div class="card">

                <img class="card-img-top img-fluid" src="https://images.freeimages.com/images/large-previews/85a/daisy-s-1375598.jpg"  width="100" height="100" alt="Card image cap"><div class="card-body">
                  <h4 class="card-title">Card 7</h4>
                  <p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
                  <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
                </div>
              </div>
            </div>
          </div>
          <a class="carousel-control-prev" href="#myCarousel" role="button" data-slide="prev">
            <span class="carousel-control-prev-icon" aria-hidden="true"></span>
            <span class="sr-only">Previous</span>
          </a>
          <a class="carousel-control-next" href="#myCarousel" role="button" data-slide="next">
            <span class="carousel-control-next-icon" aria-hidden="true"></span>
            <span class="sr-only">Next</span>
          </a>
        </div>

  </div>


</div>

. ts code:

$("#myCarousel").on("slide.bs.carousel", function(e) {
      var $e = $(e.relatedTarget);
      var idx = $e.index();
      var itemsPerSlide = 3;
      var totalItems = $(".carousel-item").length;

      if (idx >= totalItems - (itemsPerSlide - 1)) {
        var it = itemsPerSlide - (totalItems - idx);
        for (var i = 0; i < it; i++) {
          // append slides to end
          if (e.direction == "left") {
            $(".carousel-item")
              .eq(i)
              .appendTo(".carousel-inner");
          } else {
            $(".carousel-item")
              .eq(0)
              .appendTo($(this).find(".carousel-inner"));
          }
        }
      }
    });
  }

.scss code

  .carousel-inner .active,
.carousel-inner .active + .carousel-item,
.carousel-inner .active + .carousel-item + .carousel-item {
  display: block;
}

.carousel-inner .carousel-item.active:not(.carousel-item-right):not(.carousel-item-left),
.carousel-inner .carousel-item.active:not(.carousel-item-right):not(.carousel-item-left) + .carousel-item,
.carousel-inner .carousel-item.active:not(.carousel-item-right):not(.carousel-item-left) + .carousel-item + .carousel-item {
  transition: none;
}

.carousel-inner .carousel-item-next,
.carousel-inner .carousel-item-prev {
  position: relative;
  transform: translate3d(0, 0, 0);
}

.carousel-inner .active.carousel-item + .carousel-item + .carousel-item + .carousel-item {
  position: absolute;
  top: 0;
  right: -33.3333%;
  z-index: -1;
  display: block;
  visibility: visible;
}

/* left or forward direction */
.active.carousel-item-left + .carousel-item-next.carousel-item-left,
.carousel-item-next.carousel-item-left + .carousel-item,
.carousel-item-next.carousel-item-left + .carousel-item + .carousel-item,
.carousel-item-next.carousel-item-left + .carousel-item + .carousel-item + .carousel-item {
  position: relative;
  transform: translate3d(-100%, 0, 0);
  visibility: visible;
}

/* farthest right hidden item must be abso position for animations */
.carousel-inner .carousel-item-prev.carousel-item-right {
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
  display: block;
  visibility: visible;
}

/* right or prev direction */
.active.carousel-item-right + .carousel-item-prev.carousel-item-right,
.carousel-item-prev.carousel-item-right + .carousel-item,
.carousel-item-prev.carousel-item-right + .carousel-item + .carousel-item,
.carousel-item-prev.carousel-item-right + .carousel-item + .carousel-item + .carousel-item {
  position: relative;
  transform: translate3d(100%, 0, 0);
  visibility: visible;
  display: block;
  visibility: visible;
}
like image 752
Madpop Avatar asked Aug 25 '18 15:08

Madpop


People also ask

Why is bootstrap carousel not sliding?

In browsers where the Page Visibility API is supported, the carousel will avoid sliding when the webpage is not visible to the user (such as when the browser tab is inactive, the browser window is minimized, etc.).

How can you control the speed of the carousel item in a slideshow?

Approach 1: We can control the animation by using the data interval attribute of each carousel item. The given example is the best example for understanding this concept. The Data-interval attribute is used to set the interval time between two carousel item by default its value is 3000 milliseconds.

How do I slow down bootstrap carousel?

If you are using bootstrap carousel, then you need to provide the data-interval attribute on your main carousel div to change the speed of carousel. Ex. Here the value 3000 is in msec. If you are not using bootstrap carousel, then specify more details what exactly you have done so far.

How do I stop auto sliding in bootstrap 5 carousel?

Use the [interval]="'0'" input. This will disable the auto-sliding feature. Here's the link to the Carousel Documentation.


1 Answers

You may find it easier to write your own carousel behaviour, and remove any reliance on jquery. You can still use Bootstrap to style.

We can also use Angular animations to retain the animation behaviour. (Please note that this is the first time I've used Angular animations, so there may be a neater way of doing this)

First step is to create a directive, which handles the next / prev behaviour:

  @Input() animationDuration = 500;

  private slideLeft: AnimationFactory;
  private slideRight: AnimationFactory;
  private slideInLeft: AnimationFactory;
  private slideInRight: AnimationFactory;

  constructor(private el: ElementRef, private _builder: AnimationBuilder) {
  }

  ngOnInit() {
    this.slideLeft = this._builder.build([
      style({ transform: 'translateX(0)' }),
      animate(this.animationDuration, style({ transform: 'translateX(-100%)' })),
      style({ transform: 'translateX(0)' }),
    ]);

    this.slideRight = this._builder.build([
      style({ transform: 'translateX(0)' }),
      animate(this.animationDuration, style({ transform: 'translateX(100%)' })),
      style({ transform: 'translateX(0)' }),
    ]);

    this.slideInLeft = this._builder.build([
      style({ transform: 'translateX(100%)', right: 0 }),
      animate(this.animationDuration, style({ transform: 'translateX(0)' })),
      style({ right: 'initial' })
    ]);

    this.slideInRight = this._builder.build([
      style({ transform: 'translateX(-100%)', left: 0 }),
      animate(this.animationDuration, style({ transform: 'translateX(0)' })),
      style({ left: 'initial' })
    ]);
  }

  next(steps) {
      let active = this.el.nativeElement.querySelectorAll('.carousel-item.active');
      let inactive = this.el.nativeElement.querySelector('.carousel-item:not(.active)');
      // Start the animation
      this.animateAll(active, this.slideLeft);
      // Start the slide in animation for the next element
      this.preMoveElement(inactive);
      this.slideInLeft.create(inactive).play();

      setTimeout(() => {
        // Move the last element to start and make it active.
        active = this.el.nativeElement.querySelectorAll('.carousel-item.active');
        inactive = this.el.nativeElement.querySelector('.carousel-item:not(.active)');
        active[0].classList.remove('active');
        this.el.nativeElement.insertBefore(active[0], null);
        inactive.classList.add('active');
        if (steps && steps - 1 > 0) {
          this.next(steps - 1);
        }
      }, this.animationDuration);
   // }
  }

  prev(steps) {
    const active = this.el.nativeElement.querySelectorAll('.carousel-item.active');
    const children = this.el.nativeElement.children;
    const lastChild = children[children.length - 1];
    // Start the animation
    this.animateAll(active, this.slideRight);
    // Start the slide in animation for the next element
    this.preMoveElement(lastChild);
    this.slideInRight.create(lastChild).play();


    setTimeout(() => {
      // Remove the active class
      const lastActive = active[active.length - 1];
      lastActive.classList.remove('active');
      // Move the last element to the start, and make it active
      this.el.nativeElement.insertBefore(lastChild, children[0]);
      lastChild.classList.add('active');
      if (steps && steps - 1 > 0) {
        this.prev(steps - 1);
      }
    }, this.animationDuration);
  }

  private animateAll(elements: any[], animation: AnimationFactory) {
    elements.forEach(element => {
      animation.create(element).play();
    });
  }

  private preMoveElement(element) {
    element.style.display = 'block';
    element.style.position = 'absolute';
    setTimeout(() => {
      element.style = null;
    }, this.animationDuration);
  }

You can then access the prev and next functions from the HTML:

Change the carousel-inner element, like so:

<div class="carousel-inner row w-100 mx-auto" #cara="Carousel">

We can then use the cara variable to access the public functions:

  <a class="carousel-control-prev" role="button" (click)="cara.prev(3)">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="carousel-control-next" role="button" (click)="cara.next(3)">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>

Finally, mark 3 of the carousel-items as .active, so that 3 are displayed at the same time.

Here is a StackBlitz demo

like image 97
user184994 Avatar answered Oct 18 '22 19:10

user184994