Кастомизация progress bar для swiper.js

введите сюда описание изображения

Всех приветствую! Подскажите,пожалуйста, как можно кастомизировать данный progress bar. Использую swiper.js. Чтобы он срабатывал у активного слайда. Сейчас,при такой инициализации, просто появляется одна большая сплошая линия.

 const bigSlider = new Swiper('.big-slider',{
        spaceBetween: 10,
        autoplay: {
            delay: 4000
        },
        loop: true,
        pagination: {
            el: '.swiper-pagination',
            type: 'progressbar',
        },
        
    })

Ответы (1 шт):

Автор решения: De.Minov

Вариант с использованием bullet custom и SVG

const swiper = new Swiper('.swiper', {
  loop: true,
  autoplay: {
    delay: 5000,
    disableOnInteraction: false
  },
  pagination: {
    el: '.swiper-pagination',
    bulletClass: 'swiper-pagination-bullet-custom',
    bulletActiveClass: 'swiper-pagination-bullet-custom--active',
    renderBullet: function(index, className) {
      return `<div class="${className}" data-index="${index}">
        <svg viewbox="0 0 20 20">
            <circle r="9" cx="10" cy="10" fill="none" stroke-width="1.5" stroke="#fff"/>
        </svg>
      </div>`
    },
    clickable: true
  },
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },
  on: {
    init: function() {
      const _self = this;
      
      _self.el.style.setProperty('--delay', _self.params.autoplay.delay);
      
      _self.el.addEventListener('mouseenter', function() {
        _self.el.classList.add('swiper--pause');
        _self.autoplay.stop();
      });

      _self.el.addEventListener('mouseleave', function() {
        _self.el.classList.remove('swiper--pause');
        _self.autoplay.start();
      });
    }
  }
});
.swiper {
  width: 100%;
}

.swiper-slide {
  display: block;
  width: 100%;
  background: #555;
  position: relative;
}

.swiper-slide::before {
  content: '';
  display: block;
  width: 100%;
  height: 0;
  padding-top: 55%;
}

.swiper-slide-wrap {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
}

/* Нужное для вас */

.swiper-pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  width: auto;
  max-width: 100%;
}

.swiper-pagination-bullet-custom {
  display: block;
  flex-shrink: 0;
  width: 25px;
  height: 25px;
  position: relative;
  cursor: pointer;
}

.swiper-pagination-bullet-custom::before {
  content: '';
  display: block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: rgba(255,255,255,.65);
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

.swiper-pagination-bullet-custom:not(:last-child) {
  margin-right: 5px;
}

.swiper-pagination-bullet-custom svg {
  display: none;
  width: 100%;
  height: 100%;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) rotate(-90deg);
}
.swiper-pagination-bullet-custom--active svg {
  display: block;
}

.swiper-pagination-bullet-custom--active svg circle {
  stroke-dasharray: 56.5563;
  stroke-dashoffset: 56.5563;
  animation: BulletProgress calc(var(--delay) * 1ms) linear forwards;
}

.swiper-pagination-bullet-custom--active::before {
  background-color: #fff;
}

@keyframes BulletProgress {
  to {
    stroke-dashoffset: 0;
  }
}

.swiper--pause .swiper-pagination-bullet-custom--active svg circle {
  animation: none;
}
<script src="https://unpkg.com/swiper@8/swiper-bundle.min.js"></script>
<link href="https://unpkg.com/swiper@8/swiper-bundle.min.css" rel="stylesheet"/>

<!-- Slider main container -->
<div class="swiper">
  <!-- Additional required wrapper -->
  <div class="swiper-wrapper">
    <!-- Slides -->
    <div class="swiper-slide">
      <div class="swiper-slide-wrap">Slide 1</div>
    </div>
    <div class="swiper-slide">
      <div class="swiper-slide-wrap">Slide 2</div>
    </div>
    <div class="swiper-slide">
      <div class="swiper-slide-wrap">Slide 3</div>
    </div>
    <div class="swiper-slide">
      <div class="swiper-slide-wrap">Slide 4</div>
    </div>
    <div class="swiper-slide">
      <div class="swiper-slide-wrap">Slide 5</div>
    </div>
  </div>
  <!-- If we need pagination -->
  <div class="swiper-pagination"></div>

  <!-- If we need navigation buttons -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
</div>

P.s.
Значение delay в JS должно совпадать с animation-duration у .swiper-pagination-bullet-custom--active svg circle в CSS.


v0.1 - Добавил возможность остановки таймера автопереключения слайдов, вместе с ним сбрасывается анимация "прелоадера".
Так же теперь не нужно самостоятельно добавлять в CSS animation-duration, он будет добавляться при инициализации слайдера при помощи CSS перменных.

→ Ссылка