Требуется зациклить анимацию

140
17 июля 2019, 13:30

Столкнулся с проблемой зацикливания анимация.

Задача состоит в том, чтобы сделать бегущую строку (настоящую), и для этого требуется сделать перестановку элементов, на данный момент это есть, но теперь требуется зациклить весь этот процесс.

Воспроизвести проблему можно сразу при запуске, после красной строки должно быть продолжение.

(function($) { 
  $.fn.uspSlider = function(options) { 
 
    var settings = $.extend({ 
      'widthSliderResize': 1000, 
      'countElements': 3, 
      'tagDOM': 'li', 
      'showClassAppendAndPrepend': true, 
      'showDebugElements': true, 
      'duration': 7000, 
      'easing': 'linear' 
    }, options); 
 
    var mainContainer = this; 
 
    var sliderController = { 
      items: [], 
      itemsCloned: { 
        append: [], 
        prepend: [] 
      }, 
      width: 0, 
      fullWidth: 0, 
      fullWidthWithMargin: 0, 
      countElements: settings['countElements'], 
      tagDOM: settings['tagDOM'], 
      margin: { 
        container: '0 0 0 0', 
        element: '0 10px 0 0', 
        _left: 0, 
        _right: 10, 
        lastChildElement: false 
      } 
    }; 
 
    var methods = { 
      _init: function() { 
 
        $(sliderController.tagDOM, mainContainer).each(function() { 
          sliderController.items.push($(this)); 
          sliderController.width += $(this).outerWidth(true); 
        }); 
 
        var sliderItemsLength = sliderController.items.length; 
 
        for (var i = 0; i < sliderItemsLength; i++) { 
          var j = sliderItemsLength - (i + 1); 
          sliderController.items[i].clone().addClass('cloned append').appendTo(mainContainer); 
          sliderController.items[j].clone().addClass('cloned prepend').prependTo(mainContainer); 
        } 
 
        var sliderContainerAllElemetsLength = sliderController.countElements * sliderController.countElements; 
 
        $(sliderController.tagDOM, mainContainer).each(function(index) { 
          if ($(this).hasClass('append')) { 
            sliderController.itemsCloned.append.push($(this)); 
          } else if ($(this).hasClass('prepend')) { 
            sliderController.itemsCloned.prepend.push($(this)); 
          } 
 
          if (!settings['showClassAppendAndPrepend']) { 
            $(this).removeClass('append prepend'); 
          } 
 
          if (index < sliderContainerAllElemetsLength - 1 && !sliderController.margin.lastChildElement) { 
            $(this).css('margin', sliderController.margin.element); 
          } 
        }); 
 
        var widthWithMargin = (sliderContainerAllElemetsLength * (sliderController.margin._right + sliderController.margin._left)); 
 
        sliderController.fullWidth = ((sliderController.width * sliderController.countElements) + widthWithMargin); 
 
        sliderController.fullWidthWithMargin = sliderController.fullWidth + widthWithMargin; 
 
        mainContainer.width(sliderController.fullWidth); 
 
        if (settings['showDebugElements']) { 
          console.table(sliderController); 
        } 
 
        methods.uspBlockController(); 
      }, 
      _destroy: function() { 
        console.log('Destroy here!'); 
      }, 
      uspBlockController: function() { 
        var windowInnerWidth = window.innerWidth; 
 
        var controlClonedSliderElements = function(value) { 
          $(sliderController.tagDOM, mainContainer).each(function(index) { 
            if ($(this).hasClass('cloned')) { 
              value ? $(this).removeClass('cloned-disable') : $(this).addClass('cloned-disable'); 
            } 
          }); 
        } 
 
        if (windowInnerWidth < settings['widthSliderResize']) { 
          mainContainer.addClass('activeMobileUSP') 
 
          if (sliderController.items.length <= 0) { 
            methods._init(); 
          } 
 
          controlClonedSliderElements(true); 
 
          mainContainer.width(sliderController.fullWidth); 
 
          var count = 1 
          tmpCount = 1, 
            itemsPositionLeft = []; 
 
          var animated = function(element) { 
            element.animate({ 
              uspWidth: sliderController.fullWidth 
            }, { 
              step: function(widthForFirstAnimate, fx) { 
 
                $(this).css('-webkit-transform', "translate(" + -widthForFirstAnimate + "px, 0)"); 
 
                var checkedAnimate = function() { 
                  if (mainContainer.find(sliderController.tagDOM + ':nth-child(' + count + ')').is(':offscreen')) { 
 
                    var thisElement = mainContainer.find(sliderController.tagDOM + ':nth-child(' + count + ')'); 
 
                    itemsPositionLeft.push(widthForFirstAnimate); 
 
                    function tmpAnimate(tmpElement) { 
 
                      console.log(tmpElement); 
 
                      tmpElement.stop(true, false); 
 
                      tmpElement.animate({ 
                        uspWidth: sliderController.fullWidth + itemsPositionLeft[tmpElement.index()] 
                      }, { 
                        start: function() { 
                          console.log(tmpElement.index()); 
 
                          tmpCount++; 
 
                          if (tmpCount > (sliderController.countElements * sliderController.countElements)) { 
                            tmpCount = 1; 
                          } 
                        }, 
                        step: function(widthForSecondAnimate, fx) { 
                          var stepVariable = 40; // Переменная которая отвечает за прижимание к левому краю первоначального animate 
 
                          $(this).find('a').css("color", "red"); 
 
                          $(this).css("-webkit-transform", "translate(" + (-widthForSecondAnimate + sliderController.fullWidth - stepVariable) + "px, 0)"); 
 
                          if ($(this).is(':offscreen') && ($(this).index() + 1) == tmpCount) { 
 
                            // Тому элементу, который скрылся за левую часть экрана, обновляем анимацию. 
 
                            tmpAnimate(mainContainer.find(sliderController.tagDOM + ':nth-child(' + tmpCount + ')')); 
 
                          } 
                        }, 
                        duration: settings['duration'], 
                        easing: settings['easing'] 
                      }); 
                    }; 
 
                    count++; 
 
                    if (count > (sliderController.countElements * sliderController.countElements)) { 
                      count = 1; 
                    } 
 
                    tmpAnimate(thisElement); 
                  } 
                } 
 
                checkedAnimate(); 
              }, 
              duration: settings['duration'], 
              easing: settings['easing'] 
            }); 
          }; 
 
          animated(mainContainer.find(sliderController.tagDOM)); 
 
        } else if (windowInnerWidth > settings['widthSliderResize'] && 
          mainContainer.hasClass('activeMobileUSP')) { 
          mainContainer.removeClass('activeMobileUSP'); 
 
          controlClonedSliderElements(false); 
 
          mainContainer.find(sliderController.tagDOM).stop(true, true).animate({ 
            uspWidth: 0 
          }).css('-webkit-transform', "translate(0, 0)").width('auto'); 
 
          mainContainer.width('auto'); 
        } 
      } 
    } 
 
    $(window).resize(function() { 
      methods.uspBlockController(); 
    }); 
 
    $.expr.filters.offscreen = function(el) { 
      var rect = el.getBoundingClientRect(); 
      return ( 
        (rect.x + rect.width) < 0 || 
        (rect.y + rect.height) < 0 || 
        (rect.x > window.innerWidth || rect.y > window.innerHeight) 
      ); 
    }; 
 
    methods.uspBlockController(); 
  }; 
 
  $('.usp-block-container').find('.usp-block-details').uspSlider({ 
    'widthSliderResize': 486, 
    'showClassAppendAndPrepend': true, 
    'showDebugElements': false 
  }); 
 
})(jQuery);
html, 
body { 
  margin: 0; 
  padding: 0; 
} 
 
h1 { 
  text-align: center; 
} 
 
.usp-block-container { 
  width: 100%; 
  background-color: black; 
  overflow: hidden; 
} 
 
.usp-block-details { 
  color: white; 
  text-align: center; 
  padding: 15px 0; 
  margin: 0 auto; 
} 
 
.usp-block-details .item { 
  display: inline-block; 
  text-transform: uppercase; 
  margin-right: 10px; 
} 
 
.usp-block-details .item a { 
  color: white; 
  font-family: 'Consolas', sans-serif; 
  font-size: 16px; 
  text-decoration: none; 
} 
 
.usp-block-details .item:last-child { 
  margin-right: 0; 
} 
 
 
/* Style for usp-controller */ 
 
.cloned-disable { 
  display: none !important; 
}
<script src="https://code.jquery.com/jquery-1.10.2.js"></script> 
 
<h1>USP loop</h1> 
<div class="usp-block-container"> 
  <ul class="usp-block-details"> 
    <li class="item"><a href="">First</a></li> 
    <li class="item"><a href="">Second</a></li> 
    <li class="item"><a href="">Third</a></li> 
  </ul> 
</div>

Прошу обратить внимание на строку 211. Заранее благодарен за помощь.

READ ALSO
Uncaught (in promise) TypeError: The &#39;listener&#39; parameter must be a function

Uncaught (in promise) TypeError: The 'listener' parameter must be a function

Вызываю функцию addListener из библиотеки WebMidi, третий параметр называется 'listener'Требуется, чтобы этот параметр был функцией (В моём случае это...

115
Побитовое ИЛИ, проблемка

Побитовое ИЛИ, проблемка

Переписываю некий код с яваскрипта на пхп

135
Как отловить событие &ldquo;доскроллили до самого низа страницы&rdquo;?

Как отловить событие “доскроллили до самого низа страницы”?

Как сделать, когда доскролишь до самого низа страницы, чтобы поменялся background, как отловить тот момент, когда уже уперлись в самый низ страницы...

139
Не вешается событие keydown javascript

Не вешается событие keydown javascript

Привет все есть такой код

148