Слайдер доходит не до конца

Нашёл в интернете слайдер, кинул на сайт и всё работает. Но мне не нравилось что нету отступов между блоками (не особо красиво). Я поставил отступы с права у каждого блока по 30px. В итоге слайдер стал "прокручиваться" не до конца. Отступ ставил в .slider__item Если его убрать, то будет всё ок. Но мне нужно с ними, как решить эту "ошибку"?

https://jsfiddle.net/zfweuong/

  <div class="slider">
    <div class="slider__wrapper">
      <div class="slider__item">
        <div style="height: 250px; background: orange;">1</div>
      </div>
      <div class="slider__item">
        <div style="height: 250px; background: green;">2</div>
      </div>
      <div class="slider__item">
        <div style="height: 250px; background: violet;">3</div>
      </div>
      <div class="slider__item">
        <div style="height: 250px; background: coral;">4</div>
      </div>
      <div class="slider__item">
        <div style="height: 250px; background: brown;">5</div>
      </div>
      <div class="slider__item">
        <div style="height: 250px; background: orchid;">6</div>
      </div>
      <div class="slider__item">
        <div style="height: 250px; background: aqua;">7</div>
      </div>
       <div class="slider__item">
        <div style="height: 250px; background: aqua;">8</div>
      </div>
      <div class="slider__item">
        <div style="height: 250px; background: aqua;">9</div>
      </div>
      <div class="slider__item">
        <div style="height: 250px; background: aqua;">10</div>
      </div>
      <div class="slider__item">
        <div style="height: 250px; background: aqua;">11</div>
      </div>
      <div class="slider__item">
        <div style="height: 250px; background: aqua;">12</div>
      </div>
      <div class="slider__item">
        <div style="height: 250px; background: aqua;">13</div>
      </div>
      <div class="slider__item">
        <div style="height: 250px; background: aqua;">14</div>
      </div>
    </div>
    <a class="slider__control slider__control_left" href="#" role="button"></a>
    <a class="slider__control slider__control_right slider__control_show" href="#" role="button"></a>
  </div>


    body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  color: #fff;
  height: 3000px;
}

.slider {
  position: relative;
  overflow: hidden;
}

.slider__wrapper {
  display: flex;
  transition: transform 0.6s ease;
}

.slider__item {
  flex: 0 0 300px;
  max-width: 300px;
  margin-right: 30px;
}

.slider__control {
  position: absolute;
  top: 50%;
  display: none;
  align-items: center;
  justify-content: center;
  width: 40px;
  color: #fff;
  text-align: center;
  opacity: 0.5;
  height: 50px;
  transform: translateY(-50%);
  background: rgba(0, 0, 0, .5);
}

.slider__control_show {
  display: flex;
}

.slider__control:hover,
.slider__control:focus {
  color: #fff;
  text-decoration: none;
  outline: 0;
  opacity: .9;
}

.slider__control_left {
  left: 0;
}

.slider__control_right {
  right: 0;
}

.slider__control::before {
  content: '';
  display: inline-block;
  width: 20px;
  height: 20px;
  background: transparent no-repeat center center;
  background-size: 100% 100%;
}

.slider__control_left::before {
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E");
}

.slider__control_right::before {
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E");
}

.slider__item>div {
  line-height: 250px;
  font-size: 100px;
  text-align: center;
}


    'use strict';
var multiItemSlider = (function () {
  return function (selector, config) {
    var
      _mainElement = document.querySelector(selector), // основный элемент блока
      _sliderWrapper = _mainElement.querySelector('.slider__wrapper'), // обертка для .slider-item
      _sliderItems = _mainElement.querySelectorAll('.slider__item'), // элементы (.slider-item)
      _sliderControls = _mainElement.querySelectorAll('.slider__control'), // элементы управления
      _sliderControlLeft = _mainElement.querySelector('.slider__control_left'), // кнопка "LEFT"
      _sliderControlRight = _mainElement.querySelector('.slider__control_right'), // кнопка "RIGHT"
      _wrapperWidth = parseFloat(getComputedStyle(_sliderWrapper).width), // ширина обёртки
      _itemWidth = parseFloat(getComputedStyle(_sliderItems[0]).width), // ширина одного элемента    
      _positionLeftItem = 0, // позиция левого активного элемента
      _transform = 0, // значение транфсофрмации .slider_wrapper
      _step = _itemWidth / _wrapperWidth * 100, // величина шага (для трансформации)
      _items = []; // массив элементов
    // наполнение массива _items
    _sliderItems.forEach(function (item, index) {
      _items.push({ item: item, position: index, transform: 0 });
    });

    var position = {
      getMin: 0,
      getMax: _items.length - 1,
    }

    var _transformItem = function (direction) {
      if (direction === 'right') {
        if ((_positionLeftItem + _wrapperWidth / _itemWidth - 1) >= position.getMax) {
          return;
        }
        if (!_sliderControlLeft.classList.contains('slider__control_show')) {
          _sliderControlLeft.classList.add('slider__control_show');
        }
        if (_sliderControlRight.classList.contains('slider__control_show') && (_positionLeftItem + _wrapperWidth / _itemWidth) >= position.getMax) {
          _sliderControlRight.classList.remove('slider__control_show');
        }
        _positionLeftItem++;
        _transform -= _step;
      }
      if (direction === 'left') {
        if (_positionLeftItem <= position.getMin) {
          return;
        }
        if (!_sliderControlRight.classList.contains('slider__control_show')) {
          _sliderControlRight.classList.add('slider__control_show');
        }
        if (_sliderControlLeft.classList.contains('slider__control_show') && _positionLeftItem - 1 <= position.getMin) {
          _sliderControlLeft.classList.remove('slider__control_show');
        }
        _positionLeftItem--;
        _transform += _step;
      }
      _sliderWrapper.style.transform = 'translateX(' + _transform + '%)';
    }

    // обработчик события click для кнопок "назад" и "вперед"
    var _controlClick = function (e) {
      if (e.target.classList.contains('slider__control')) {
        e.preventDefault();
        var direction = e.target.classList.contains('slider__control_right') ? 'right' : 'left';
        _transformItem(direction);
      }
    };

    var _setUpListeners = function () {
      // добавление к кнопкам "назад" и "вперед" обрботчика _controlClick для событя click
      _sliderControls.forEach(function (item) {
        item.addEventListener('click', _controlClick);
      });
    }

    // инициализация
    _setUpListeners();

    return {
      right: function () { // метод right
        _transformItem('right');
      },
      left: function () { // метод left
        _transformItem('left');
      }
    }

  }
}());

var slider = multiItemSlider('.slider')

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

Автор решения: frozencoast

При расчёте ширины элемента нужно учитывать и отступы (margins)

_itemWidth = parseFloat(getComputedStyle(_sliderItems[0]).width) 
  + (parseFloat(_itemStyle.marginRight) || 0)
  + (parseFloat(_itemStyle.marginLeft) || 0) 

Также нужно рассчитать минимальное значение сдвига влево, чтобы избежать пустого простанства справа от последнего элемента

_minTransform = (_wrapperWidth - _itemWidth * (_sliderItems.length - 1) + 
  (parseFloat(_itemStyle.marginRight) || 0)) / _wrapperWidth * 100

При трансформации нужно учесть минимальное значение сдвига влево:

_sliderWrapper.style.transform = 'translateX(' + Math.max(_transform, _minTransform) + '%)';

Вот рабочий вариант - https://jsfiddle.net/frozencoast/zuqyg5s8/

→ Ссылка