Swiperjs Sync the slide changes with a custom progress bar

So I’m attempting to make a custom progress bar that splits into multiple bars depending on the number of slides and progresses through each synced with the duration of the slide speed and slide duration.

Issue: While the bar does progress, the timing slowly goes off until it’s entirely out of sync with the slide changes. I know it is likely to do with the calculation for the progress duration, but I’m not sure how I could calculate this differently to keep it in sync.

JS

// homepage carousel
let autoPlayDelay = 1500;


const mySwiper = new Swiper('.vertical-swiper', {
  slidesPerView: 1,
  spaceBetween: 0,
  mousewheel: false,
  autoplay: {
    delay: autoPlayDelay
  },
  keyboard: true,
  loop: false,
  direction: 'vertical',
  speed: 1500,
  height: "465",
  navigation: {
    nextEl: '.swiper-btn-next',
    prevEl: '.swiper-btn-prev',
  },
});



let progress = document.querySelector('.swiper-progress-bar .progress');
const progressSections = document.querySelector('.swiper-progress-bar .progress-sections');

let slidersCount = mySwiper.params.loop ? mySwiper.slides.length - 2 : mySwiper.slides.length;
let widthParts = 100 / slidersCount;

function initProgressBar() {
  let calcProgress = (slidersCount - 1) * (autoPlayDelay + mySwiper.params.speed);
  calcProgress += autoPlayDelay;
  progress.style.width = '0%';
  progress.classList.remove('stopped');
  progress.animate([{
    width: '0%'
  }, {
    width: '100%'
  }], calcProgress, 'linear');
}

initProgressBar();

for (let i = 0; i < slidersCount; i++) {
  const span = document.createElement('span');
  progressSections.appendChild(span);
}

// Cache DOM queries
const activeHeader = document.querySelector('.header-text');
const activeEyebrow = document.querySelector('.eyebrow-text');

function updateSlide(index) {
  const slide = mySwiper.slides[index];
  const collectionsEyebrow = slide.querySelector('.slide__eyebrow');
  const collectionsHeader = slide.querySelector('.slide__heading');

  if (activeHeader && activeEyebrow && collectionsEyebrow && collectionsHeader) {
    // Slide up
    activeHeader.classList.add('is--move');
    activeEyebrow.classList.add('is--move');

    // Replace text
    setTimeout(() => {
      activeHeader.textContent = collectionsHeader.textContent;
      activeEyebrow.textContent = collectionsEyebrow.textContent;
    }, 300);

    // Slide down
    setTimeout(() => {
      activeHeader.classList.remove('is--move');
      activeEyebrow.classList.remove('is--move');
    }, 400);
  }
}

window.addEventListener('load', function() {
  // Call update header & eyebrow on page load
  const activeIndex = mySwiper.activeIndex;
  updateSlide(activeIndex);
});

// Call updateSlide function on slide change
mySwiper.on('slideChange', function() {
  const activeIndex = mySwiper.activeIndex;
  updateSlide(activeIndex);


  // update slidersCount and widthParts
  slidersCount = mySwiper.params.loop ? mySwiper.slides.length - 2 : mySwiper.slides.length;
  widthParts = 100 / slidersCount;


  let progress = document.querySelector('.swiper-progress-bar .progress');

  // Calculate progress bar width based on current slide index and autoplay delay
  const slideDelay = mySwiper.params.autoplay.delay;
  const progressWidth = (activeIndex + 1) * widthParts;
  const progressTime = (activeIndex + 1) * slideDelay;

  if ((this.progress === -0 || (this.progress === 1 && this.params.loop)) && !progress.parentElement.classList.contains('stopped')) {
    progress.style.width = '0';
    if (this.activeIndex === 0) {
      initProgressBar();
    }
  }

  /*   if (progress.parentElement.classList.contains('stopped')) {
      progress.animate(
        [
          { width: progress.style.width },
          { width: progressWidth + '%' }
        ],
        {
          duration: progressTime,
          easing: 'linear'
        }
      );
    } */

  if (progress.parentElement.classList.contains('stopped')) {
    const progressWidth = Math.round(widthParts * (mySwiper.activeIndex + 1));
    progress.animate({
        width: progressWidth + '%'
      },
      mySwiper.params.speed,
      'linear'
    );
  }

});

mySwiper.on('touchMove', function() {
  const progress = document.querySelector('.swiper-progress-bar .progress');
  progress.style.animationPlayState = 'paused';
  progress.parentElement.classList.add('stopped');
});


mySwiper.on('beforeSlideChangeStart', function() {
  const slide = this.el.querySelector('.swiper-slide');
  const slideImg = slide.querySelector('.img-container img');

  const setClasses = !slide.classList.contains('swiper-slide-active');
  setClass(slideImg, 'swiper-slide-active', 'remove');

  if (setClasses) {
    slide.classList.toggle('swiper-slide-active');
    this.el.querySelector('.swiper-slide').classList.toggle('expand-img');
  }
});

function setClass(el, className, fnName) {
  el.classList[fnName](className);
}

Example: https://jsfiddle.net/Fitzlegit/5Lo8vuxk/87/