2
\$\begingroup\$

This is meant to present main content in the carousel above with a painless navigation below where the moment you start dragging the content keeps up.

I was trying to avoid having to drag once per slide or press "next" many times. Also the previous and next classes are added for effect. Will look quite different in production, it's the functionality I'm showing off here.

Here's a working codepen: https://codepen.io/Julix/pen/xexawP

// Flickity slider from external js: flickity.pkgd.js
// Prev- and next classes from external js: https://codepen.io/desandro/pen/wWQQwN.js 
"use strict";

var $carousel = $('.carousel-main').flickity({
  "wrapAround": true,
  "draggable": true,
  "prevNextButtons": false,
  "pageDots": false
});
var $nav = $('.carousel-nav').flickity({
  "on": {
    ready: choseCenterSlide,
    scroll: choseCenterSlide
  },
  "asNavFor": ".carousel-main",
  "wrapAround": true,
  "percentPosition": false,
  "draggable": true,
  "pageDots": false,
  "prevNextButtons": false
});
;
var navDragging = false;
$nav.on('dragStart.flickity', function () {
  return navDragging = true;
});
$nav.on('settle.flickity', function () {
  return navDragging = false;
});
$nav.data('flickity').resize();

var isWrapped = true;
var isInstant = true;
function choseCenterSlide() {
  // check if this.x is within slideableWidth
  var currentX = this.x > 0 ? -this.slideableWidth + this.x : this.x < -this.slideableWidth ? this.slideableWidth + this.x : this.x; // calculate closest slide

  var distances = this.slides.map(function (slide) {
    return -slide.target;
  });
  var closestDistance = distances.reduce(function (prev, curr) {
    return Math.abs(curr - currentX) < Math.abs(prev - currentX) ? curr : prev;
  });
  var closestSlideIndex = distances.indexOf(closestDistance); // early return

  if (closestSlideIndex == this.scrollSlideIndex) return; // register 

  if (this.scrollSlideIndex == null) this.scrollSlideIndex = this.selectedIndex; // change scrollSlide

  this.slides[this.scrollSlideIndex].cells.forEach(function (cell) {
    cell.element.classList.remove('is-closest');
  });
  this.slides[closestSlideIndex].cells.forEach(function (cell) {
    cell.element.classList.add('is-closest');
  }); // update state variable

  this.scrollSlideIndex = closestSlideIndex; // update selectedSlide

  if (navDragging) {
    this.select(this.scrollSlideIndex, isWrapped, isInstant);

    if (this.navCompanion) {
      this.navCompanion.select(this.scrollSlideIndex);
    }
  }
}
/* external css: flickity.css */


.carousel-nav .carousel-cell.is-selected {
  background: lightblue;
}
.carousel-nav .carousel-cell.is-closest {
  background: #ffd466;
}

.carousel-nav .carousel-cell.is-closest {
  background: #ffd466;
}
.carousel-nav .carousel-cell.is-selected {
  background: lightblue;
}

.carousel-nav .carousel-cell.is-nav-selected {
  background: linear-gradient(to left, darkred, #640404, darkred);
}
.carousel-nav .carousel-cell.is-previous {
  background: linear-gradient(to left, darkred, lightgreen);
}
.carousel-nav .carousel-cell.is-next {
  background: linear-gradient(to right, darkred, lightgreen);
}



* { box-sizing: border-box; }

body { font-family: sans-serif; }

.carousel {
  background: transparent;
}

.carousel-main .carousel-cell,
.carousel-nav .carousel-cell {
  height: 100px;
  margin-right: 10px;
  background: #8C8;
  border-radius: 5px;
  counter-increment: carousel-cell;
}


.carousel-main .carousel-cell {
    height: 200px;
    line-height: 200px;
    width: 66%;
}
.carousel-nav .carousel-cell {
  width: 300px;
}

/* cell number */
.carousel-cell:before {
  display: block;
  text-align: center;
  content: counter(carousel-cell);
  font-size: 80px;
  color: white;
}


.carousel-nav {
  
}
.carousel-nav .carousel-cell {
  width: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://npmcdn.com/flickity@2/dist/flickity.pkgd.js"></script>
<script src="https://codepen.io/desandro/pen/wWQQwN.js"></script>


<h1>Main attraction</h1>
<div class="carousel carousel-main">
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
</div>

<h2>Navigation</h2>

<div class="carousel carousel-nav">
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
</div>

Feedback welcome! :)

\$\endgroup\$
0

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.