Responsive Auto-rotating Carousel In JavaScript – slidr

Category: Javascript , Slider | January 6, 2020
Author: betaWeb
Views Total: 107
Official Page: Go to website
Last Update: January 6, 2020
License: MIT

Preview:

Responsive Auto-rotating Carousel In JavaScript – slidr

Description:

slidr is a responsive, auto-rotating carousel slider plugin with support for navigation arrows, pagination bullets, countdown timer, play/pause controls, CSS3 transitions, and much more.

How to use it:

1. Download and place the Slidr.min.js script at the end of the document.

<script src="./dist/Slidr.min.js"></script>

2. Add slides together with carousel controls to the document.

<div id="timer" class="timer"></div>
<button data-pause class="slider__control">&#10073;&#10073;</button>
<button data-resume class="slider__control control-hidden">&#9658;</button>
<div class="slider">
  <div data-slide="slide1" class="slide">
    <h2 class="slide-title">Slide #1</h2>
  </div>
  <div data-slide="slide2" class="slide">
    <h2 class="slide-title">Slide #2</h2>
  </div>
  <div data-slide="slide3" class="slide">
    <h2 class="slide-title">Slide #3</h2>
  </div>
  <div class="slider__nav">
    <button data-prev class="slider__prev">&lt;</button>
    <div id="nav__dots" class="nav__dots"></div>
    <button data-next class="slider__prev">&gt;</button>
  </div>
  <div id="slider_progress" class="slider_progress"></div>
</div>

3. The JavaScript to enable the carousel.

document.addEventListener('DOMContentLoaded', () => {

  const $timer = document.getElementById('timer')
  const $progress = document.getElementById('slider_progress')
  const $dotNav = document.getElementById('nav__dots')
  const $pauseBtn = document.querySelector('[data-pause]')
  const $resumeBtn = document.querySelector('[data-resume]')
  const populateTimer = timeout => {
      let cpt = timeout / 1000
      $timer.innerHTML = cpt.toString()
      return window.setInterval(() => {
          cpt--
          $timer.innerHTML = cpt.toString()
      }, 1000)
  }
  const cancelTimer = timer => {
      if (timer !== null)
          window.clearInterval(timer)
  }
  const populateProgress = (progress) => {
      $progress.style.width = progress + '%'
  }

  let timer = null
  let remaining = 0
  const slider = new window.Slidr({ animate: false })
  slider
      .add({ name: 'slide1', timeout: 5 * 1000 })
      .add({
          name: 'slide2',
          timeout: 7 * 1000,
          shown() {
              this.element.querySelector('.slide-title').classList.add('shake-animation')
          },
          beforeLeave() {
              this.element.querySelector('.slide-title').classList.remove('shake-animation')
          }
      })
      .add({ name: 'slide3', timeout: 5 * 1000 })
      .listen('beforeEnter', function () {
          timer = populateTimer(this.current_slide.timeout)
          remaining = this.current_slide.timeout
          $resumeBtn.classList.add('control-hidden')
          $pauseBtn.classList.remove('control-hidden')
          populateProgress(this.progress)
          $dotNav.querySelectorAll(`[data-index]:not([data-index="${this.current_slide.index}"])`).forEach(dot => dot.classList.remove('active'))
          $dotNav.querySelector(`[data-index="${this.current_slide.index}"]`).classList.add('active')
      })
      .listen('beforeLeave', function () {
          cancelTimer(timer)
      });


  slider.slides.forEach(({ index }) => {
      let dot = document.createElement('div')
      dot.classList.add('nav__dot')
      dot.dataset.index = index

      dot.addEventListener('click', e => {
          e.preventDefault()
          slider.goTo(index)
          document.querySelectorAll('.nav__dot').forEach(d => d.classList.remove('active'))
          dot.classList.add('active')
      })

      $dotNav.appendChild(dot)
  });

  document.querySelector('[data-prev]').addEventListener('click', e => {
      e.preventDefault()
      slider.prev()
  })

  document.querySelector('[data-next]').addEventListener('click', e => {
      e.preventDefault()
      slider.next()
  })

  $pauseBtn.addEventListener('click', e => {
      e.preventDefault()
      $pauseBtn.classList.add('control-hidden')
      $resumeBtn.classList.remove('control-hidden')
      cancelTimer(timer)
      timer = null
      remaining = slider.pause()
  })

  $resumeBtn.addEventListener('click', e => {
      e.preventDefault()
      $resumeBtn.classList.add('control-hidden')
      $pauseBtn.classList.remove('control-hidden')
      timer = populateTimer(remaining)
      remaining = 0
      slider.resume()
  })

  slider.run()

})

4. The example CSS for the carousel & controls.

.slider {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.slider__nav {
  position: fixed;
  display: inline-flex;
  justify-content: space-between;
  align-items: center;
  height: 50px;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 5;
}

.slider__control,
.slider__nav .slider__prev,
.slider__nav .slider__next {
  background-color: transparent;
  border: none;
  color: #fff;
  outline: none;
  font-size: 2rem;
  font-weight: bold;
  cursor: pointer;
  padding: 5px;
  margin: 0 .5rem;
  opacity: .5;
  transition: opacity .3s;
}

.slider__control {
  position: fixed;
  width: 50px;
  height: 50px;
  line-height: 50px;
  text-align: center;
  top: 0;
  right: 0;
  opacity: .7;
  font-size: 2rem;
  z-index: 10;
  transition: opacity .3s;
}

.slider__control.control-hidden {
  display: none;
}

.slider__control:hover,
.slider__nav .slider__prev:hover,
.slider__nav .slider__next:hover,
.slider__nav .nav__dot:hover,
.slider__nav .nav__dot.active {
  opacity: .8;
}

.slider__nav .nav__dots {
  display: inline-flex;
  justify-content: space-around;
  align-items: center;
}

.slider__nav .nav__dot {
  background-color: #fff;
  opacity: 0.5;
  transition: opacity .3s;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin: 0 .25rem;
  cursor: pointer;
}

.slide {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 4;
  vertical-align: middle;
  text-align: center;
  opacity: 0;
  transform: translateY(-50px);
  transition: transform .3s, opacity .3s;
}

.slide.active {
  opacity: 1;
  transform: translateY(0);
}

.slide .slide-title {
  position: absolute;
  top: 50%;
  right: 0;
  left: 0;
  width: 100%;
  text-align: center;
  transform: translateY(-50%);
  font-size: 3rem;
  color: #fff;
  opacity: .8;
  margin: 0;
  padding: 0;
}

.slide[data-slide="slide1"] {
  background-color: #4273ff;
}

.slide[data-slide="slide2"] {
  background-color: #ff3c5f;
}

.slide[data-slide="slide3"] {
  background-color: #ff6bfb;
}

.slide .slide-title.shake-animation {
  animation: shake 0.82s cubic-bezier(.36,.07,.19,.97) both;
  transform: translate3d(0, -50%, 0);
  backface-visibility: hidden;
  perspective: 1000px;
}

.timer {
  position: fixed;
  width: 50px;
  height: 50px;
  line-height: 50px;
  text-align: center;
  top: 0;
  left: 0;
  color: #fff;
  opacity: .7;
  font-size: 2rem;
  z-index: 10;
}

.slider_progress {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  width: 0;
  height: 4px;
  z-index: 10;
  background-color: #fff;
  opacity: .5;
  transition: width .3s;
}

@keyframes shake {
  10%, 90% {
      transform: translate3d(-1px, -50%, 0);
  }

  20%, 80% {
      transform: translate3d(2px, -50%, 0);
  }

  30%, 50%, 70% {
      transform: translate3d(-4px, -50%, 0);
  }

  40%, 60% {
      transform: translate3d(4px, -50%, 0);
  }
}

You Might Be Interested In:


Leave a Reply