[JavaScript] array positionen nach wirbel muster (tutorial hinzugekommen)

Dieses Thema im Forum "Webentwicklung" wurde erstellt von onip, 14. April 2011 .

  1. 14. April 2011
    Zuletzt von einem Moderator bearbeitet: 15. April 2017
    array positionen nach wirbel muster (tutorial hinzugekommen)

    hi,

    ich komm irgendwie nicht auf die lösung, daher würde ich mich
    um tipps und anregungen sehr freuen.

    folgendes:
    ich hab eine matrix (array) das z.b. aus 3x3 felder besteht.
    das wird mir als schachbrett dargestellt.

    z.b. so:

    0 1 2
    3 4 5
    6 7 8

    nun soll ein weiters array so erstellt werden, dass
    den ablauf einer schnecke oder wirbel erstellt.

    das neue array sollte wie folge generiet werden.
    0, 1, 2, 5, 8, 7, 6, 3, 4

    hier mal ne grafik:
    Bild

    könnt ihr mir erklären wie sich sowas generiert.
    leider hab ich selbst keine ansatz.

    // edit
    hier geht's zum tutorial
     
  2. 14. April 2011
    AW: array positionen nach schnecken muster

    Mhh also es sieht recht einfach aus, ich editiert mal in 10 minuten, ich glaub das lässt sich algorithmisch ganz gut schreiben.

    Schließlich gehst du im array zuerst nach "rechts" dann nach ganz "unten " dann nach ganz "links" dan nach ganz "oben -1" dann nach ganz "rechts -1" dann nach ganz "unten -1" , dann nach ganz "oben -2"etc pp

    mhh ich schau mal ^^

    lg


    // ähh oh hab ich mich verschaut ?



    sicher das das "schneckenhaus" nicht dann fertig SO aussehen muss?:
    |0|1|2|
    |7|8|3|
    |6|5|4|

    ?
    Also das die Schnecke durch die aufsteigenden Zahlen symbolisiert wird?
     
  3. 14. April 2011
    AW: array positionen nach schnecken muster

    hi,

    vielleicht sollte ich mal mehr erzählen.
    folgendes.
    ich hab ein bild, das ich mir in teile zerlege um diese dann zu animieren.
    soll für ne gallerie sein.

    das bild ist z.b. 90 x 90 px
    und ich teile das in 3 spalten und 3 zeilen.
    somit ist jedes element/teil 30x30px.

    die elemente speicher ich in ein array.
    das dann so aussieht.
    Code:
    array = (
     0 => el0,
     1 => el1,
     2 => el2,
     3 => el3,
     4 => el4,
     5 => el5,
     6 => el6,
     7 => el7,
     8 => el8
    );
    
    jedes teil positioniere ich nun nach einen schachbrett muster.
    also so:
    0 1 2
    3 4 5
    6 7 8

    das einblenden der elemente kann ich nun mit verschiedenen abläufen tun.
    variant1:
    einfach von 0 - 8 einblenden

    variante2:
    array umkehren und von 8 - 0 einblenden

    variante3:
    array mischen und zufällig einblenden

    variante4:
    könnte eben das schneckenmuster (blöder begriff, vielleicht nennt man das wirbel, naja) sein


    du verstehst mein anliegen.
    anhand dieser matrix stehen einige nette effekt zur verfügung um bilder einzulenden.
    ich könnte nicht nur einblenden. es könnte auch top, left oder width, height eingestzt werden.
     
  4. 14. April 2011
    AW: array positionen nach schnecken muster

    magst du uns noch kurz erklären was genau das problem dabei ist?

    ich mein, wenn du immer 9 teile hast, dann kannst du doch die ordnung statisch machen.

    effekt 1: [0,1,2,3,4,5,6,7,8]
    effekt 2: [8,7,6,5,4,3,2,1,0]
    effekt 3: [0,1,2,8,7,6,3,4,5]

    etc...
     
  5. 14. April 2011
    AW: array positionen nach schnecken muster

    ja das stimmt, das hab ich aber nicht.
    wäre ja langweilig

    ich mach per random die anzahl der spalten und reihen.
    daher weiß ich nie wie das array aussieht.
     
  6. 14. April 2011
    AW: array positionen nach schnecken muster

    Verdammt unschön, aber für eine rein mathematische Lösung fehlen mir einfach die Mathekenntnisse:
    PHP:
    $matrix  = array();

    #$matrix[0] = array('a', 'b', 'c');
    #$matrix[1] = array('d', 'e', 'f');
    #$matrix[2] = array('g', 'h', 'i');

    $matrix [ 0 ] = array( 'a' 'b' 'c' 'd' 'e' );
    $matrix [ 1 ] = array( 'f' 'g' 'h' 'i' 'j' );
    $matrix [ 2 ] = array( 'k' 'l' 'm' 'n' 'o' );
    $matrix [ 3 ] = array( 'm' 'q' 'r' 's' 't' );

    function 
    schlange ( $matrix ) {
        
    $schlange  array_shift ( $matrix );
        for (
    $i  0 $i  count ( $matrix )- 1 ; ++ $i ) {
            
    $schlange [] =  array_pop ( $matrix [ $i ]);
        }
        
    $schlange  array_merge ( $schlange array_reverse ((array) array_pop ( $matrix )));
        for (
    $i  count ( $matrix )- 1 $i  >=  0 $i --) {
            
    $schlange [] =  array_shift ( $matrix [ $i ]);
        }
        if (!empty(
    $matrix )) {
            
    $schlange  array_merge ( $schlange schlange ( $matrix ));
        }
        return 
    $schlange ;
    }
     
  7. 14. April 2011
    AW: array positionen nach schnecken muster

    ich hab was gefunden, dass mir die x&y koordinaten ausgibt
    Code:
    var elAr = [];
    var ph = partscountH;
    var pw = partscountW;
    var x = 0;
    var y = 0;
    var way = 0;
    var nr = 0;
    var dowhile = true;
    while (dowhile) {
     nr = way == 0 || way == 2 ? pw : ph;
     for (i = 1; i <= nr; i++) {
     posAr = partsSwirl['p'+x+y];
     elAr.include(this.partsDiv[posAr]);
     if (i != nr) {
     switch (way) {
     case 0:
     y++;
     break;
     case 1:
     x++;
     break;
     case 2:
     y--;
     break;
     case 3:
     x--;
     break;
     default:
     break;
     }
     }
     }
     way = (way + 1) % 4;
     switch (way) {
     case 0:
     pw--;
     y++;
     break;
     case 1:
     ph--;
     x++;
     break;
     case 2:
     pw--;
     y--;
     break;
     case 3:
     ph--;
     x--;
     break;
     default:
     break;
     }
     aktHW = this.maxMath(ph, pw) - this.minMath(ph, pw);
     if (pw <= aktHW && ph <= aktHW) {
     dowhile = false;
     }
    }
    
    da ich zuvor die teile erstellen muss, hab ich mir ein objekt angelegt, indem ich x&y notiere.

    z.b.
    Code:
    var partsDiv = [];
    var partsSwirl = {};
    // schleife
    ...
    p = ('p'+(mcT/h)+(mcL/w));
    partsSwirl[p] = i;
    ...
    // schleife ende
    /*
    p = keyname für partsSwirl objekt // z.b. p00
    i = value für partsSwirl objekt (array position von partsDiv) // z.b. 0
    partsSwirl = {'p00': 0};
    alert(partsSwirl.p00); // 0
    */
    
    nun musste ich mir nur noch anhand der x&y position den wert von partsSwirl ausgeben lassen
    und mir das element von partsDiv array holen.
    Code:
    while (dowhile) {
     nr = way == 0 || way == 2 ? pw : ph;
     for (i = 1; i <= nr; i++) {
     posAr = partsSwirl['p'+x+y];
     elAr.include(this.partsDiv[posAr]);
     ...
    
    nun hab ich mein elAr mit der richtigen reihenfolge befüllt und ich kann animieren

    das scheint so gut zu funktionieren.
    vielleicht versteht jemand die schleife und kann dieses ggf. optimieren.
     
  8. 14. April 2011
    AW: array positionen nach schnecken muster

    rein logisch:

    Code:
    var matrix = [
     ["a", "b", "c", "d", "e"],
     ["f", "g", "h", "i", "j"],
     ["k", "l", "m", "n", "o"],
     ["p", "q", "r", "s", "t"]
    ];
    
    var zeilen = matrix.length,
     spalten = matrix[0].length;
    
    var result = [];
     
    for (var c = 0, m = zeilen / 2; c < m; ++c) {
     // zeile nach rechts
     for (var i = c, l = matrix[c].length - c; i < l; ++i)
     result.push(matrix[c][i]);
     
     // jeweils den letzten nach unten
     for (var i = c + 1, l = zeilen - c - 1; i < l; ++i)
     result.push(matrix[i][spalten - c - 1]);
     
     // zeile rückwärts
     for (var i = spalten - c -1; i > c; --i)
     result.push(matrix[zeilen - c - 1][i]);
     
     // jeweils den ersten nach oben
     for (var i = zeilen - c - 1; i > 0; --i)
     result.push(matrix[i][c]);
    }
    
    result.pop();
    alert(result); // a,b,c,d,e,j,o,t,s,r,q,p,k,f,g,h,i,n,m,l
    funktioniert aber nur wenn die anzahl der zeilen durch 4 teilbar ist, lässt sich aber optimieren hab aber nur grad keinen bock

    komplizierte da, wollt eigl. was ganz anderes machen und bin voll dran hängen geblieben
     
  9. 14. April 2011
    AW: array positionen nach schnecken muster

    hey,

    ich dachte auch, dass das irgendwie schnell zu machen sei.
    einfach wäre es natürlich gewesen ein festes raster einzustellen,
    dann wären die schleifen nicht nötig.
    mit dem skript oben geht es mit jeder anzahl spalten und reihen.
    ich werde morgen mal ein komplettes tutorial zusammen stellen,
    dass elemente erstellt, diese als wirbel sortiert und animiert.

    apropo tutorial.
    was wurde eigentlich aus dem tutorial-bereich?
    fand ich gut um zu stöbern und anzubieten.
     
  10. 15. April 2011
    AW: array positionen nach schnecken muster

    der bereich wurde aufgrund mangelnder aktivität entfernt. über die suchfunktion findest du die themen nun in "webentwicklung"
     
  11. 15. April 2011
    Zuletzt von einem Moderator bearbeitet: 15. April 2017
    AW: array positionen nach schnecken muster

    so, wie angekündigt.
    poste ich hier ein kleines tut.

    1. step
    wir machen uns erstmal das html. ich hab noch ein trace für die ausgabe dazugetan.
    Code:
    <div id="container" style="width: 550px; height: 400px; overflow: hidden; position: relative; border: 1px solid #f00;"></div>
    <div id="trace"></div>
    
    2. step
    wir erstellen uns die elemente (teile) mit hintergrundbild, positionieren die teile,
    legen das element in ein array ab, und in ein objekt notieren wir uns die position (x&y).
    ich hab ein objekt für die notiz gewählt, da man schön einfach darauf zugreifen kann.
    natürlich wäre es möglich in das objekt gleich noch das element fest zu halten (wäre auch sinnfoll).
    ich hab allerding so schon begonnen und alles umstellen will ich grad nicht.

    // edit
    alles was mit swirl zutun hat wird in v2 nicht mehr benötigt.
    //
    Code:
    // nur für trace
    var tracePartsAr = [];
    var traceSwirlAr = [];
    //
    // elemente erstellen
    var divEl = $('container');
    var divW = divEl.getSize().x;
    var divH = divEl.getSize().y;
    var partscountW = Number.random(3, 8);
    var partscountH = Number.random(3, 8);
    var partW = Math.ceil(divW/partscountW);
    var partH = Math.ceil(divH/partscountH);
    var partsDiv = [];
    var partsSwirl = {};
    for (var i = 0; i < partscountW*partscountH; i++) {
     bgPosLeft = partW*-i;
     bgPosTop = partH*-i;
     
     mcT = Math.floor(i/partscountW)*partH;
     mcL = (i % partscountW) * partW;
     mcW = partW;
     mcH = partH;
     bgPosLeft = -mcL;
     bgPosTop = -mcT;
     //swirlAr
     p = ('p'+(mcT/mcH)+(mcL/mcW));
     partsSwirl[p] = i;
     // trace
     tracePartsAr.include(i);
     //
     partsDiv[i] = new Element('div', {
     'id': 'efx_swirl'+i,
     'class': 'efx_swirl',
     'html': 'key: '+i+'<br />x: '+(mcL/mcW)+'<br />y: '+(mcT/mcH),
     styles: {
     'position': 'absolute',
     'z-index': i,
     'overflow': 'hidden',
     'opacity': 0,
     'top': mcT,
     'left': mcL,
     'width': mcW,
     'height': mcH,
     'background': 'transparent url(img/saarschleife.jpg) '+bgPosLeft+'px '+bgPosTop+'px no-repeat',
     'text-align': 'center',
     'border': '1px solid #fff',
     'text-shadow': '2px 2px 1px #000'
     }
     }).inject(divEl);
    }
    
    3. step v1
    Spoiler
    nun die berechnung für den wirbel. es werden mir x&y koordinaten berechnet.
    da uns nun die koordinaten bekannt sind und wir ja zuvor die koordinaten notiert haben,
    brauchen wir also nur noch das element von partsDiv in das elAr array eintragen.
    elAr hat dann die gewünscht reihenfolge und wir können animieren.

    Code:
    // swirl berechnen
    var elAr = [];
    var pW = partscountW;
    var pH = partscountH;
    var x = 0;
    var y = 0;
    var way = 0;
    var nr = 0;
    var dowhile = true;
    while (dowhile) {
     nr = way == 0 || way == 2 ? pW : pH;
     for (i = 1; i <= nr; i++) {
     posAr = partsSwirl['p'+x+y];
     elAr.include(partsDiv[posAr]);
     // trace
     traceSwirlAr.include(posAr);
     //
     if (i != nr) {
     switch (way) {
     case 0:
     y++;
     break;
     case 1:
     x++;
     break;
     case 2:
     y--;
     break;
     case 3:
     x--;
     break;
     default:
     break;
     }
     }
     }
     way = (way + 1) % 4;
     switch (way) {
     case 0:
     pW--;
     y++;
     break;
     case 1:
     pH--;
     x++;
     break;
     case 2:
     pW--;
     y--;
     break;
     case 3:
     pH--;
     x--;
     break;
     default:
     break;
     }
     aktHW = (pH < pW ? pW : pH) - (pH > pW ? pW : pH);
     if (pW <= aktHW && pH <= aktHW) {
     dowhile = false;
     }
    }
    
    3. step v2 (@Breyndot-Echse)
    hier eine vereinfachung von v1 zur berechnung des wirbels.
    es ist keine berechnung und notierung der x&y koordianten mehr nötig.
    Code:
    // swirl berechnen
    var elAr = [];
    var height = partscountH;
    var width = partscountW;
    var addend = 1;
    var number = 0;
    var depth = 0;
    for (var i = 0; i < width * height; ++i) {
     elAr.push(partsDiv[number]);
     if (addend > 0) {
     if (addend == 1 && number == (width-1) * (depth+1)) {
     addend = width;
     } else if (addend == width && number == (width * height) - ((width+1) * depth) - 1) {
     addend = -1;
     }
     } else if (addend < 0) {
     if (addend == -1 && number == width * (height-1) - ((width-1) * depth)) {
     addend = -width;
     } else if (addend == -width && number == (depth+1) * width + depth) {
     addend = 1;
     ++depth;
     }
     }
     number += addend;
    }
    
    da in eine richtung langweilig ist und wir etwas abwechslung haben wollen,
    machen wir noch eine prüfung ob das elAr umgedreht werden soll.
    Code:
    // vor- rückwerts
    var reverseAr = Number.random(0, 1);
    if (reverseAr){
     elAr = elAr.reverse();
    }
    
    und hier schonmal die ausgabe (trace)
    Code:
    // trace
    $('trace').innerHTML += 'Container: '+divW+'x'+divH+'px<br />Spalte: '+partscountW+'<br />Reihe: '+partscountH+'<br />Teile: '+partW+'x'+partH+'px<br />';
    $('trace').innerHTML += '<p>partsDiv:<br />'+tracePartsAr+'</p>';
    $('trace').innerHTML += '<p>elAr:<br />'+traceSwirlAr+'</p>';
    $('trace').innerHTML += '<p id="ani" style="color:#f00">animation läuft ('+(!reverseAr ? 'vor' : 'zurück')+') ...</p>';
    
    4. step
    nun können wir animieren.
    Code:
    // ani
    var fx = [];
    elAr.each(function(el, i) {
     fx[i] = new Fx.Morph(el, {
     duration: 2000,
     transition: Fx.Transitions.Expo.easeInOut
     });
     fx[i].start.pass({
     'opacity': 1
     }, fx[i]).delay(100*i);
    });
    
    da es unter umständen noch wichtig ist zu wissen ob die animation fertig ist,
    emittlen wir die letzte position aus elAr und fügen der letzten animation noch ein anweisung hinzu.
    Code:
    // letzte animation fertig
    lastDiv = elAr.length-1;
    fx[lastDiv].chain(function() {
     $('ani').setStyle('color', '#0f0').innerHTML = 'animation fertig</p>';
    });
    
    und das wars.

    jetzt fragen sich die ein oder anderen, was soll das ganze.
    nunja, einmal weil ich ein netter mensch bin, ich mein tuts die ich für alles erstelle gerne teile,
    das ne schöne spielerei ist und auf dieser basis eine menge möglichkeiten offen sind.

    wir können zu opacity noch zusätzlich in die animation, das backgroundimage, width, height oder top, left animieren.
    und wenn swirl ausgereitzt ist, dann eben elAr zufällig mischen, oder in reihenfolge vor- zurück ...
    ach hört auf, die grenzen sind offen für eine richtig tolle galerie

    ich hoffe euch gefällt das keine tut.
    und wer das ganze beispiel hunterladen möchte, kann das unter folgenden links tun:
    - v1
    - v2 (danke Breyndot-Echse)

    ich persönlich nutze nur das MooTools framework.
    vielleicht könnte das jemand in ein anderes framework (z.b. jQuery) adaptieren
    und es hier mit einstellen.

    - hier eine adaption zur berechnung des wirbels von Breyndot-Echse auf PHP

    danke an allen teilnehmern, die zu diesem ergebniss geführt haben.

    viele grüße
    onip
     
  12. 15. April 2011
    AW: array positionen nach wirbel muster (tutorial hinzugekommen)

    Oh, dass das ganze in JS gewünscht ist, habe ich wohl überlesen...


    Ich hab noch ein bisschen rumprobiert:
    PHP:
    function  snake ( $width $height ) {
        
    $resultArray  = array();
        
        
    $addend  1 ;
        
    $number  $depth  0 ;
        for (
    $i  0 $i  $width  $height ; ++ $i ) {
            
    $resultArray [] =  $number ;
            
    //Die Schlange bewegt sich nach rechts oder unten
            
    if ( $addend  0 ) {
                
    //Nach unten schicken
                
    if ( $addend  ==  &&  $number  == ( $width - 1 ) * ( $depth + 1 )) {
                    
    $addend  $width ;
                
    //Nach links schicken
                
    } elseif ( $addend  ==  $width  &&  $number  == ( $width  $height ) - (( $width + 1 ) *  $depth ) -  1 ) {
                    
    $addend  = - 1 ;
                }
            }
            
    //Die Schlange bewegt sich nach links oder oben
            
    elseif ( $addend  0 ) {
                
    //Nach oben schicken
                
    if ( $addend  == - &&  $number  ==  $width  * ( $height - 1 ) - (( $width - 1 ) *  $depth )) {
                    
    $addend  = - $width ;
                
    //Nach rechts schicken
                
    } elseif ( $addend  == - $width  &&  $number  == ( $depth + 1 ) *  $width  $depth ) {
                    
    $addend  1 ;
                    ++
    $depth ;
                }
            }

            
            
    $number  +=  $addend ;
        }
        return 
    $resultArray ;
    }
    bzw in JS:
    Code:
    function snake(width, height) {
     var addend = 1;
     var number = 0;
     var depth = 0;
     var resultArray = new Array();
     for (var i = 0; i < width * height; ++i) {
     resultArray.push(number);
     if (addend > 0) {
     if (addend == 1 && number == (width-1) * (depth+1)) {
     addend = width;
     } else if (addend == width && number == (width * height) - ((width+1) * depth) - 1) {
     addend = -1;
     }
     } else if (addend < 0) {
     if (addend == -1 && number == width * (height-1) - ((width-1) * depth)) {
     addend = -width;
     } else if (addend == -width && number == (depth+1) * width + depth) {
     addend = 1;
     ++depth;
     }
     }
     number += addend;
     }
     return resultArray;
    }
    Die Funktion berechnet die Eckpunkte der Schlange und kann desshalb auf eine Matrix verzichten. Es werden alle Keys in einem Array zurückgegeben.
     
  13. 15. April 2011
    AW: array positionen nach wirbel muster (tutorial hinzugekommen)

    hey, danke.
    das werd ich gleich mal ausprobieren.
    php function ist doch super, wer weiß wo man das mal gebrauchen kann, danke.

    // edit
    läuft super und ist neu eingebunden.
    tut ist dementsprechend angepasst, danke.
     
  14. 15. April 2011
    AW: array positionen nach wirbel muster (tutorial hinzugekommen)

    ich weiss wofuer:
    Captchas.Ist ne gute Idee mit dem Pfad
     
  15. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.