2016-06-24 2 views
0

Ich versuche, den Shellsort-Algorithmus zu visualisieren.Weiter für die Schleife, nachdem die Animation beendet ist

Zuerst erstelle ich Zufallszahlen und füge sie als ein P-Tag innerhalb eines div hinzu. Danach schiebe ich alle Divs mit der passenden Klasse in ein Array, das der Shellsort-Funktion oben zugewiesen ist. Das funktioniert gut, aber ich kann die Animation nicht richtig funktionieren.

Es animiert nur die letzten zwei Divs in der Schleife.

Meine Absicht war, dass die zwei Divs, die getauscht werden, nach unten und wieder zurück gleiten. Der shellsort soll danach weitermachen.

Ich habe viele verschiedene Lösungen ausprobiert, aber ich kann nicht so funktionieren, wie ich es möchte.

Die fertige Version sollte die beiden divs visuell austauschen .. also, wenn Sie eine schnelle Lösung oder einen Link für mich haben könnte, wäre das genial.

Vielen Dank im Voraus.

edit:

Die HTML und CSS verwendet:

<!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> 

Die 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%; 
} 

Es gibt nichts hier funktional, aber vielleicht hilft es .. :)

Der JQuery Code:

$(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; 
    } 
}); 
+0

könnten Sie bitte zugehörige HTML hinzufügen und CSS hier? – vijayP

+0

danke für die Freigabe von HTML und CSS. Ich habe Ihren Code überprüft, konnte aber nicht den Code finden, der aufgerufen wird, um einen zufälligen Button zu erstellen, und auch die Funktion 'getInt'. Könnten Sie bitte Code in Ihrer 'script.js' Datei teilen. Es wird leicht sein, den Code zu reparieren, sobald wir ihn hier reproduzieren können. Vielen Dank. – vijayP

+0

Ich habe den jquery Code zu meinem Beitrag hinzugefügt! Danke für Ihr Interesse :) – NecNator

Antwort

0

Es sieht so aus, als wären die im Timeout verwendeten Variablen nur referenziert - so wird für jede Schleife ein neues Timeout für das aktuelle val gesetzt (= erwartet) + die Werte in der Funktion der zuvor erstellten Timeout-Funktion werden geändert gut (= unerwartet, schätze ich).

Eine mögliche Lösung wäre, die Animation nicht asynchron zu tun. Vielleicht wäre es auch eine Funktion über eine "currying" -Funktion ala

function createAnimation(a, b) { 
    return function() { 
     animatTthis($('#' + a), 500); 
     animatTthis($('#' + b), 500); 
    }; 
} 

und in unserer Art erstellen arbeiten:

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

this helps

Edit: Animation an der gleichen Zeit ist ein anderes Problem, als Sie gefragt haben. Anyways: Das Problem ist, dass die Iteration viel schneller als 250ms ist, also alle Animationen fast gleichzeitig starten.

Sie müssen die Animation über die Animationsrückrufe nacheinander in die Warteschlange stellen. Mein Vorschlag ist, zuerst zu sortieren und Informationen zu sammeln, um zu animieren. Anschließend können Sie eine verkettete Funktion erstellen, um sie nach Bedarf zu animieren.

Ich habe ein Beispiel geschaffen, die einige Ihrer ursprünglichen Methoden, die von einem „Animator“, die anschließend die erforderlichen Informationen und die Durchführung der Animation zu sammeln ist in der Lage ersetzt:

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(); 
       } 
      }); 
     }); 
    } 
} 
} 

Dieses von einer Animation zu funktionieren scheint Sicht Kasse diese Geige: https://jsfiddle.net/91Lp7k90/

Abgesehen davon, die elemt ids nicht scheinen richtig zu sein, das ist, warum ich einige Konsolenausgabe ist ebenso hinzugefügt haben ...

+0

Leider scheint das das Problem nicht zu beheben:/ – NecNator

+0

Es animiert alle Divs gleichzeitig ... – NecNator

+0

Vielen Dank für Ihre Mühe !!! Ich werde es mir später genauer ansehen und berichten :) – NecNator