动画结束后继续循环

时间:2016-06-24 12:17:30

标签: jquery loops animation

我正在尝试将shellsort算法可视化。

  function shellSort (a) {

  for (var h = a.length; h = parseInt(h / 2);) {
      for (var i = h; i < a.length; i++) {
          var k = getInt(a[i].id);
          var helper = a[i];
          for (var j = i; j >= h && k < getInt(a[j - h].id); j -= h){

            var idA = a[j].id;
            var idB = a[j - h].id;

            setTimeout(function(){
              animatTthis($('#' + idA), 500);
              animatTthis($('#' + idB), 500);
              console.log('animate!');
            },250);

            a[j] = a[j - h];
          }
          a[j] = helper;
      }
  }
  return a;  
}

首先,我创建随机数,并将它们作为p-tag添加到div中。之后,我将所有div与适配类推送到一个Array中,该Array被赋予上面的shellsort函数。 这很好但我无法使动画正常工作。

  function animatTthis(targetElement, speed) {
  $(targetElement).animate({ top: "50px"},
  {
      duration: speed,
      complete: function ()
      {
          setTimeout(function(){
            $(targetElement).animate({ top: "0px" },{
              duration: speed,
              complete: function (){
                  console.log('animate!');
              }
            });
        },500);
      }
  });
};

它只会动画循环中最后两个Div。

我的意图是交换掉的两个Div再次向下滑动。在此之后,应该继续进行解决方案。

我尝试了许多不同的解决方案,但我无法按照我想要的方式工作。

完成的版本应该在视觉上交换两个div ..所以,如果你有一个快速的解决方案或链接对我来说会很棒。

提前致谢。

编辑:

使用的HTML和CSS:

    <!DOCTYPE html>
<html>
<head>
<script src="jquery-3.0.0.js"></script>
<script src="script.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/color/jquery.color-2.1.2.js"></script>

<link rel="stylesheet" href="stylesheet.css">

<title>Shell Sort</title>
</head>
<body>
<h1 >Shell- sort</h1>
<button id='randomNumbers'>Numbers!</button> // creeates random numbers
<button id='okay'>Okay!</button>  //starts the shellsort
<div id='container'>
  <div id="element1" class="test"><p class='value' id='e1ID'></p></div>
  <div id="element2" class="test"><p class='value' id='e2ID'></p></div>
  <div id="element3" class="test"><p class='value' id='e3ID'></p></div>
  <div id="element4" class="test"><p class='value' id='e4ID'></p></div>
  <div id="element5" class="test"><p class='value' id='e5ID'></p></div>
  <div id="element6" class="test"><p class='value' id='e6ID'></p></div>
</div>


</body>
</html>

CSS:

h1{
    color:red;
}
.value{
    margin: 0;
    text-align: center;
    line-height:75px;
    font-size: 30px;
    font-weight: bold;
}
.test{
        background-color: red;
        height: 75px;
        width: 75px;
        position: relative;
        float:left;
        margin: 10px;
        border-radius: 50%;
}

这里没有任何功能,但也许它会有所帮助.. :)

jquery代码:

   $(document).ready(function(){

//#############---giveRandomNumbers----#############
  $("#randomNumbers").click(function(){
    var numbers = [];
    for(var i = 0; i < 6; i++){
      var $random = Math.floor((Math.random() * 100) + 1);
      numbers.push($random);
    }

      for(var int = 0; int < numbers.length; int++){
          $('#e'+(int + 1)+'ID').text(numbers[int]);
      }
    });

  $('#okay').click(function(){
      var $ids = $('.test');
      shellSort($ids);

      for(var int = 0; int < $ids.length; int++){
        console.log(getInt($ids[int].id));
        $("#container").append($ids[int]);
      }
    });

    //#############---getIntegerOfDiv----#############
  function getInt(id) {
    var $number = parseInt($('#'+ id).find("p").text());
    return $number;
  };
  //#############---animationCarry----#############
  function createAnimation(a, b) {
      return function() {
          animatTthis($('#' + a), 500);
          animatTthis($('#' + b), 500);
      };
  }
//#############---animation----#############
  function animatTthis(targetElement, speed) {
  $(targetElement).animate({ top: "50px"},
  {
      duration: speed,
      complete: function (){
          setTimeout(function(){
            $(targetElement).animate({ top: "0px" },{
              duration: speed,
              complete: function (){
                  console.log('animate!');
              }
            });
        },500);
      }
  });
};
//#############---shellSort----#############
  function shellSort (a) {

      for (var h = a.length; h = parseInt(h / 2);) {
          for (var i = h; i < a.length; i++) {
              var k = getInt(a[i].id);
              var helper = a[i];
              for (var j = i; j >= h && k < getInt(a[j - h].id); j -= h){
                a[j] = a[j - h];
                var idA = a[j].id;
                var idB = a[j - h].id;
                setTimeout(createAnimation(idA, idB), 250);

              }
              a[j] = helper;
          }
      }
      return a;
  }
});

1 个答案:

答案 0 :(得分:0)

看起来,超时中使用的变量只是被引用 - 所以对于每个循环,为当前val(= expected)设置新的超时+以前创建的超时函数的函数中的值也被修改(=意外,我猜)。

一种可能的解决方案是不异步进行动画。 也许它也可以通过“currying”函数ala

创建一个函数
function createAnimation(a, b) {
    return function() {
        animatTthis($('#' + a), 500);
        animatTthis($('#' + b), 500);
    };
}

以我们的方式:

setTimeout(createAnimation(idA, idB), 250);

希望这有帮助

编辑:动画同时是你要求的另一个问题。 无论如何:问题是,迭代比250ms快得多,所以所有的动画几乎同时开始。

您需要一个接一个地通过动画回调对动画进行排队。我的建议是首先进行排序并收集如何动画的信息。之后,您可以根据需要创建一个链式函数进行动画处理。

我创建了一个示例,它通过“动画师”替换了一些原始方法,该动画师能够收集所需信息并在之后执行动画:

var Animator = {

 toAnimate: [],

 add: function(a, b) {
    Animator.toAnimate.push({
        a: '#' + a,
        b: '#' + b
    });
 },

 execute: function() {

     var lastCallback = function() {
         Animator.toAnimate = [];
     };

     for (var idx = 0; idx<Animator.toAnimate.length; idx++) {
         var elem = Animator.toAnimate[idx];
         var animateB = Animator.createAnimation(elem.b, 500, lastCallback);
         var animateA = Animator.createAnimation(elem.a, 500, animateB);

         lastCallback = animateA;
     }

     lastCallback();
 },

 createAnimation: function(id, speed, cb) {
     console.log('creating animation for ' + id);
     return function() {
        $(id).animate({top: '50px'}, speed, function() {
           $(id).animate({top: '0px'}, speed, function() {
              if (typeof(cb) === 'function') {
                 cb();
              }
           });
        });
     }
 }
}

这似乎从动画的角度来看,结帐这个小提琴:https://jsfiddle.net/91Lp7k90/

除此之外,elemt id似乎不正确,这也是我添加一些控制台输出的原因......