Правильный способ написать идеальную анимацию, используя jquery

Текущий сценарий:

У меня есть список divs который содержит набор элементов, который прокручивается автоматически в зависимости от количества divs подарок. Этот список divs находится внутри parentdiv и с фиксированным height,

Требования:

  • Не анимировать, т.е. прокрутить, если длина divs присутствует внутри менее 4.
  • Оживить с той же скоростью до последнего div и прокрутите назад снизу вверх наоборот.
  • Остановить свиток при наведении на любого ребенка div,

Выполнено:

  • Прокрутка выполнена, т.е. она не прокручивается, если присутствует менее 4 элементов.
  • Прокрутка останавливается при зависании любого ребенка div,
  • Анимируйте до нижнего элемента и начните с начала.

Проблемы, стоящие в настоящее время:

  • Прокрутка не происходит с той же скоростью. Он начинается медленно, увеличивает скорость и заканчивается медленно.
  • После зависания, которое прекращает прокрутку, когда оно начинается снова, оно начинает медленно снова.
  • Достигнув конца, он остается там в течение нескольких секунд, а затем начинается с начала.

ДЕМОНСТРАЦИЯ

HTML

<div id="events_partial" class="container body-content col-md-12 col-lg-12 set-max-height">
    <div class="row sec-container" id="secContainer">
        <div style="top: -550.242px; opacity: 1;" id="secDetails">
            <div class="container">
                <p><h3><strong> Program in Place 1 &nbsp;on&nbsp;11/22/2015</strong></h3></p>
                <p>
                  Program Description which is a very long text on document and it  can be more than 2 lines
                </p>
            </div>
            <div class="container">
                <p><h3><strong> Program in Place 1 &nbsp;on&nbsp;11/22/2015</strong></h3></p>
                <p>
                  Program Description which is a very long text on document and it  can be more than 2 lines
                </p>
            </div>
            <div class="container">
                <p><h3><strong> Program in Place 1 &nbsp;on&nbsp;11/22/2015</strong></h3></p>
                <p>
                  Program Description which is a very long text on document and it  can be more than 2 lines
                </p>
            </div>

            <div class="container">
                <p><h3><strong> Program in Place 1 &nbsp;on&nbsp;11/22/2015</strong></h3></p>
                <p>
                  Program Description which is a very long text on document and it  can be more than 2 lines
                </p>
            </div>
            <div class="container">
                <p><h3><strong> Program in Place 1 &nbsp;on&nbsp;11/22/2015</strong></h3></p>
                <p>
                  Program Description which is a very long text on document and it  can be more than 2 lines
                </p>
            </div>
            <div class="container">
                <p><h3><strong> Program in Place 1 &nbsp;on&nbsp;11/22/2015</strong></h3></p>
                <p>
                  Program Description which is a very long text on document and it  can be more than 2 lines
                </p>
            </div>
            <div class="container">
                <p><h3><strong> Program in Place 1 &nbsp;on&nbsp;11/22/2015</strong></h3></p>
                <p>
                  Program Description which is a very long text on document and it  can be more than 2 lines
                </p>
            </div>
            <div class="container">
                <p><h3><strong> Program in Place 1 &nbsp;on&nbsp;11/22/2015</strong></h3></p>
                <p>
                  Program Description which is a very long text on document and it  can be more than 2 lines
                </p>
            </div>
      </div>
    </div>
</div>

CSS

#events_partial {
    min-height: 385px !important;
    margin-top: 57px;
    overflow: hidden;
}
.set-max-height {
    max-height: 385px !important;
    padding-top: 30px !important;
}

.sec-container {
    overflow: hidden !important;
    min-height: 200px;
}

#secDetails {
    position: absolute;
    margin-top: 0px;
}

JS

var animateTime = 50000; //kept varying time because as number of items increases the speed time decreased
var shouldAnimate = true;
if ($("#secDetails .container").length < 4) {
    shouldAnimate = false;
}
if ($("#secDetails .container").length >= 4 && $("#secDetails .container").length < 9)
    animateTime = 10000;
function marqueePlay() {
   if (shouldAnimate) {
       $("#secDetails").animate(
       {
            top: $("#events_partial").height() - $("#secDetails").height(),
            opacity: 1
       }, animateTime, function () {
             $("#secDetails").css("top", 1);
             $("#secDetails").css("opacity", 1);
             marqueePlay();
       });
    }
}
marqueePlay();
$("#secDetails").hover(function () {
    $(this).stop(); //Stop the animation when mouse in
},
function () {
    marqueePlay(); //Start the animation when mouse out
});

Любая помощь высоко ценится.

1 ответ

Решение

Вот что я смог понять.

Эта проблема:

  • По умолчанию существует легкость в действиях, от которой вы хотите избавиться. Медленное начало, среднее быстрое и медленное окончание в анимации - это одно из различных замедлений, которое можно применить к анимации. В вашем случае вы явно не хотите этого и хотели бы, чтобы вещи анимировались очень линейно.
  • Я не знаю прямого способа возобновления анимации jQuery. Так что после остановки анимации при наведении, когда вы звоните marqueePlay() снова, он будет пытаться анимировать оставшееся расстояние в течение времени, определенного в animateTime переменная. Расстояние уменьшается, но время снова применяется. Следовательно, ваша анимация движется медленнее в течение небольшого времени, а затем возвращается к нормальной скорости. Просто так кажется, но на самом деле, он ведет себя именно так, как и должен.

Предлагаемое решение:

  • Исходя из моего понимания выше, ваша линейная анимация может быть легко достигнута с помощью requestAnimationFrame API.
  • Как избежать animate() Метод jQuery позволяет нам легко приостанавливать и возобновлять нашу анимацию, используя простой логический флаг.

Ниже приведен фрагмент в действии или, если вы заинтересованы в просмотре его как jsFiddle.

Snippet:

// [http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/]
window.requestAnimFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(callback){window.setTimeout(callback,1000/60);};})();
var secDetails=$('#secDetails');
var container=secDetails.find('.container');
var eventsPartial=$('#events_partial');
var currTop=0;
var destTop=eventsPartial.height()-secDetails.height()-parseInt(eventsPartial.css('margin-top'));
var isPaused=false;
var isFirstLoop=true;
var speed=1;
if(container.length>=4&&container.length<9){
 requestAnimFrame(render);
 secDetails.hover(function(){isPaused=true;},function(){isPaused=false;});
 currTop=destTop;
}
function render(){
 requestAnimFrame(render);
 if(!isPaused){
  secDetails.css({transform:'translate3d(1px,'+roundDecimal(currTop,2)+'px,0px)'});
  currTop+=!isFirstLoop?-speed:speed;
  if(currTop>0) isFirstLoop=false;
  if(currTop<=destTop) currTop=0;
 }
}
function roundDecimal(value,place){ return Math.round(value*Math.pow(10,place))/Math.pow(10,place); }
#events_partial {
 min-height: 385px !important;
 margin-top: 57px;
 overflow: hidden;
}
.set-max-height {
 max-height: 385px !important;
 padding-top: 30px !important;
}
.sec-container {
 overflow: hidden !important;
 min-height: 200px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="events_partial" class="container body-content col-md-12 col-lg-12 set-max-height">
 <div class="row sec-container" id="secContainer">
  <div id="secDetails">
   <div class="container">
                <h3><strong> Program in Place 1 &nbsp;on&nbsp;11/22/2015</strong></h3><p>Program Description which is a very long text on document and it can be more than 2 lines</p>
   </div>
   <div class="container">
    <h3><strong> Program in Place 2 &nbsp;on&nbsp;11/22/2015</strong></h3><p>Program Description which is a very long text on document and it can be more than 2 lines</p>
   </div>
   <div class="container">
    <h3><strong> Program in Place 3 &nbsp;on&nbsp;11/22/2015</strong></h3><p>Program Description which is a very long text on document and it can be more than 2 lines</p>
   </div>
   <div class="container">
    <h3><strong> Program in Place 4 &nbsp;on&nbsp;11/22/2015</strong></h3><p>Program Description which is a very long text on document and it can be more than 2 lines</p>
   </div>
   <div class="container">
    <h3><strong> Program in Place 5 &nbsp;on&nbsp;11/22/2015</strong></h3><p>Program Description which is a very long text on document and it can be more than 2 lines</p>
   </div>
   <div class="container">
    <h3><strong> Program in Place 6 &nbsp;on&nbsp;11/22/2015</strong></h3><p>Program Description which is a very long text on document and it can be more than 2 lines</p>
   </div>
   <div class="container">
    <h3><strong> Program in Place 7 &nbsp;on&nbsp;11/22/2015</strong></h3><p>Program Description which is a very long text on document and it can be more than 2 lines</p>
   </div>
   <div class="container">
    <h3><strong> Program in Place 8 &nbsp;on&nbsp;11/22/2015</strong></h3><p>Program Description which is a very long text on document and it can be more than 2 lines</p>
   </div>
  </div>
 </div>
</div>

Дайте мне знать, если что-то неясно.

PS Хотя лично мне не нравится внезапный скачок, который случается, когда он достигает самого нижнего, а затем снова выводит первый и снова начинает анимацию. Но я могу понять, что это требование в вашем сценарии, возможно, оно просто подходит для этого. Это вещь вкуса. Я хотел бы, чтобы они двигались вверх и вниз, оживляясь, как йо-йо, если бы у меня было все по-своему;).

Обновление: вот ваш йойо jsFiddle. Также забыл упомянуть, что вы можете контролировать скорость анимации с помощью speed переменная в коде. Надеюсь это поможет.

Другие вопросы по тегам