Mixpanel Pricing Slider Replica

by Hugo Carneiro

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<div class="mtu-chooser">
  <div class="mtu-slider">
    <div class="mtu-slider-wrapper">
      <div class="mtu-slider-parts">
        <div class="highlighted mtu-slider-part" style="flex-grow: 1000;">
          <div class="mtu-slider-label">100</div>
        </div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;">
          <div class="mtu-slider-label">1k</div>
        </div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;">
          <div class="mtu-slider-label">2k</div>
        </div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
        <div class="mtu-slider-part" style="flex-grow: 1000;"></div>
   ...

CSS

body {
  padding: 50px;
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
}

.mtu-chooser {
  align-items: center;
  display: flex;
  margin: 50px 0 5px;
}

.mtu-slider {
  flex-grow: 1;
  margin-right: 50px;
}

.mtu-chooser .mtu-price {
  background-color: #f6f6f6;
  border-radius: 5px;
  font-size: 16px;
  font-weight: 600;
  padding: 10px 20px;
  text-align: center;
  width: 200px;
}

.mtu-slider-wrapper {
  margin-bottom: 30px;
  margin-top: 30px;
  position: relative;
}

.mtu-slider-wrapper .mtu-slider-drag-thumb {
  background-color: #fff;
  border: 2px solid #4284fb;
  border-radius: 22px;
  cursor: pointer;
  height: 22px;
  position: absolute;
  top: -11px;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  width: 22px;
  transform-origin: center;
}

.mtu-slider-wrapper .mtu-slider-drag-thumb:not(.dragging) {
  transition: transform 100ms ease-in-out;
}

.mtu-slider-wrapper .mtu-slider-drag-thumb .mtu-thumb-label {
  color: #4284fb;
  font-weight: 600;
  position: absolute;
  top: -25px;
}

.mtu-slider-wrapper .mtu-slider-parts {
  display: flex;
}

.mtu-slider-wrapper .mtu-slider-parts .mtu-slider-part {
  background-color: #e9e9e9;
  cursor: pointer;
  flex-basis: 10px;
  height: 6px;
  margin-right: 2px;
  position: relative;
}

.mtu-slider-wrapper .mtu-slider-parts .mtu-slider-part:hover {
  background-color: #8f8f91;
}

.mtu-slider-wrapper .mtu-slider-parts .mtu-slider-part:first-child {
  border-radius: 3px 0 0 3px;
}

.mtu-slider-wrapper .mtu-slider-parts .mtu-slider-part:last-child {
  border-radius: 0 3px 3px 0;
}

.mtu-slider-wrapper .mtu-slider-parts .mtu-slider-part.highlighted {
  background-color: #4284fb;
}

.mtu-slider-wrapper .mtu-slider-parts .mtu-slider-part .mtu-slider-label {
  font-size: 12px;
  font-weight: 600;
  position: absolute;
  right: -5px;
  top: 6px;
  padding: 20px 8px;
}

JavaScript

var mtuSlider = (function() {
  var mtuOptions = {};
  var mtuSelector = '.mtu-slider';
  var sliderPartSelector = '.mtu-slider-part';
  var dragThumbSelector = '.mtu-slider-drag-thumb';
  var dragThumb = document.querySelector(dragThumbSelector);
  var dragAreaSelector = '.mtu-slider-wrapper';
  var dragArea = document.querySelector(dragAreaSelector);
  var dragAreaRect = dragArea.getBoundingClientRect();
  var dragThumbLastPosX = 0;
  var dragThumbHalfSize = 22 / 2;
  var isDragging = false;
  var sliderPartSize = 0;
  var sliderPartMargin = 2;
  var sliderDragLabelSelector = '.mtu-thumb-label';
  var sliderPartValue = 100;
  var priceSelector = '.mtu-price';
  var moneyValuePerSlider = 10;
  var selectedMTUs = sliderPartValue;

  function updatePrice(value = moneyValuePerSlider) {
    if (value > 5000) {
      $(priceSelector).html('<a href="#">Contact Sales</a>');

      return;
    }

    value = value * moneyValuePerSlider / sliderPartValue;

    $(priceSelector).text('$' + (value).toFixed(2));
  }

  function getDragThumbXPosition() {
    var elemRect = dragThumb.getBoundingClientRect();
    var positionX = elemRect.x - dragAreaRect.left;

    return positionX;
  }

  function updateDragLabel(value = sliderPartValue) {
    var text = value;

    selectedMTUs = value;

    if (value >= 1000) {
      text = value / 1000 + 'k';
    }

    if (value > 5000) {
      text = '5k+';

      selectedMTUs = 5001;
    }

    $(sliderDragLabelSelector).text(text);

    updatePrice(value);
  }

  function highlighSliderParts(element) {
    var $element = element;

    if (!($element instanceof jQuery)) {
      $element = $(element);
    }

    $element.addClass('highlighted');
    $element.prevAll(sliderPartSelector).addClass('highlighted');
    $element.nextAll(sliderPartSelector).removeClass('highlighted');
  }

  function processHighlightSliderParts() {
    var DragThumbXPosition = getDragThumbXPosition() + dragThumbHalfSize;
    var sliderNumber = Math.max(1,...