2011-11-06 8 views
15

El objetivo es producir un diseño fluido como se muestra a continuación.Algoritmo de diseño de fluido similar a la serpiente

enter image description here

Hasta ahora no tienen una función de trabajo moveBox(lastBox, "east") que realiza un seguimiento de los índices de fila y columna.

function moveBox(box, where) { 
    switch (where) { 
    case "north": 
     lastTopOffset -= BOX_HEIGHT + BOX_MARGIN; 
     box.style.top = lastTopOffset + 'px'; 
     box.style.left = lastLeftOffset + 'px'; 
     rowIndex -= 1; 
     break; 
    // ...  
    } 

Mi current code,

(function() { 
    var i, lastBox, 
     MAX_DIVS  = 72, 
     BOX_HEIGHT  = 50, 
     BOX_WIDTH  = 100, 
     BOX_MARGIN  = 5, 
     field   = document.getElementById('fieldPerimeter'), 
     fieldHeight = field.offsetHeight, 
     maxRows  = Math.floor(fieldHeight/(BOX_HEIGHT + BOX_MARGIN)), 
     rowIndex  = 0, 
     colIndex  = 0, 
     lastLeftOffset = 0, 
     lastTopOffset = 0; 

    function moveBox(box, where) { 
    switch (where) { 
     case "north": 
     lastTopOffset -= BOX_HEIGHT + BOX_MARGIN; 
     box.style.top = lastTopOffset + 'px'; 
     box.style.left = lastLeftOffset + 'px'; 
     rowIndex -= 1; 
     break; 

     case "east": 
     lastLeftOffset += BOX_WIDTH + BOX_MARGIN; 
     box.style.top = lastTopOffset + 'px'; 
     box.style.left = lastLeftOffset + 'px'; 
     colIndex += 1; 
     break; 

     case "south": 
     lastTopOffset += BOX_HEIGHT + BOX_MARGIN; 
     box.style.top = lastTopOffset + 'px'; 
     box.style.left = lastLeftOffset + 'px'; 
     rowIndex += 1; 
     break; 

     default: 
     break; 
    } 
    } 

    for (i = 0; i < MAX_DIVS; i += 1) { 
    lastBox = document.createElement('div'); 
    lastBox.className = 'box'; 
    lastBox.innerHTML = i; 
    field.appendChild(lastBox);  

    //delete me 
    if((i + 1) % 2 === 0 || (i + 1)% 3 === 0){ 
     moveBox(lastBox, "east"); 
    } else { 
     moveBox(lastBox, "south"); 
    } 
    //delete me  

// if(rowIndex < maxRows && rowIndex > 0){ 
// if (colIndex % 4 === 0){ 
//  moveBox(lastBox, "south"); 
// } else if (colIndex % 2 === 0){ 
//  moveBox(lastBox, "north"); 
// } else { 
//  moveBox(lastBox, "east"); 
// } 
// } 

    }  
})(); 

anexa divs a un contenedor y luego lo mueve. El siguiente código muestra parte de mis intentos de especificar cuándo moverse hacia el norte o hacia el sur. Pero estoy luchando para lograr el diseño deseado.

if  (colIndex % 4 === 0) { moveBox(lastBox, "south"); } 
else if (colIndex % 2 === 0) { moveBox(lastBox, "north"); } 
else       { moveBox(lastBox, "east"); } 
+6

un violín, la demostración de la imagen, y el código (gracias a Bart Kiers) en una pregunta interesante de un nuevo usuario? Upvote. Ojalá todos los nuevos usuarios tuvieran esto a su alcance. ':)' –

+0

¿Es la forma en que lo ha abordado un requisito o simplemente el que ha intentado? –

+0

He intentado otros enfoques, lo he publicado porque creo que estoy cerca, pero mi cabeza explota tratando de descubrir el algoritmo. Más tarde quiero usar un valor aleatorio para no ir al norte o al sur, pero por ahora solo necesito un poco de guía con algún pseudocódigo. Gracias Sr. Kiers por la edición. – user1032739

Respuesta

5

enter image description here

Aquí está el violín de trabajo, http://jsfiddle.net/efortis/zuY74/

Nota Codifiqué el offsetHeight para trabajar en el violín y también agregué una variable lastMove en la parte superior.

for (i = 0; i < MAX_DIVS; i += 1) { 
    lastBox = document.createElement('div'); 
    lastBox.className = 'box'; 
    lastBox.innerHTML = i; 
    field.appendChild(lastBox); 

    if (i === 0) { 
     rowIndex += 1; 
    } else { 
     if (colIndex % 4 === 0 && rowIndex < maxRows) { 
     moveBox(lastBox, "south"); 
     lastMove = "south"; 
     } else if (colIndex % 2 === 0 && rowIndex !== 1 && lastMove !== "south") { 
     moveBox(lastBox, "north"); 
     lastMove = "north"; 
     } else { 
     moveBox(lastBox, "east"); 
     lastMove = "east"; 
     } 
    } 
    } 
+0

Impresionante eso es exactamente lo que estaba buscando. Gracias Sr. Fortis – user1032739

2

Lo siguiente funciona con posiciones de cuadrícula en lugar de píxeles, con la idea de que puede convertir una posición de cuadrícula en píxeles sin problemas.

Mi cuadrícula es bastante simple. La esquina superior izquierda es (0, 0). Por lo que su cuadro está en 0 (0, 0), caja 7 está en (1, 6), etc.

Si tiene maxrows filas, a continuación, los primeros maxrows-1 artículos van en (0, 0), (0, 1), etc. Y el artículo maxrows va en (1, maxrows-1). Los siguientes artículos maxrows-1 van en (maxrows-1,2), (maxrows-2, 2), etc., y el artículo en 2*maxrows va en (0, 3).

Debería poder calcular la posición de un elemento en la cuadrícula a partir de su número. Supongamos que las matemáticas enteras están aquí.

// xblock treats each two columns as a single entity. 
xblock = itemNo/(maxrows + 1); 
xpos = 2 * xblock; 
ypos = itemNo % (maxrows + 1); 
if (ypos == maxrows) 
{ 
    // this is the last item, so we need to shift it. 
    xpos += 1; 
    ypos = maxrows - 1; 
} 

// Now, turn things upside down if xblock is odd 
if ((xblock % 2) == 1 && ypos != maxrows) 
{ 
    ypos = maxrows - ypos - 1; 
} 

En este punto, tiene la posición de la cuadrícula donde debe ir la caja. Ahora debería ser una cuestión simple convertir esa posición de cuadrícula en píxeles al multiplicar xpos por BOX_WIDTH y agregar el desplazamiento. Haga lo mismo para ypos y BOX_HEIGHT.

0

Noté que es un patrón recurrente en el diseño: partir de 0

  • cuadro de moverse hacia abajo 6 veces (REACH posición 6) Caja
  • movimiento correcto 2 veces (REACH 8)
  • la caja se mueven hacia arriba 6 veces (REACH 14)
  • caja mover hacia la derecha 2 veces (REACH 16)
  • repetición

-

var MOVES_DONE = 0; 
var MOVES_LIMIT = 72; 

/* 
* First define the three movement functions that we will use 
* (right, down and left) 
*/ 
function up(box) { 
    console.log("up"); 
} 

function down(box) { 
    console.log("down"); 
} 

function right(box) { 
    console.log("right"); 
} 

/* 
* Solution 1: 
* Starting from the top-left corner do the necessary moves to complete the 
* layout: 

      --------------------------------- 
     |          | 
     box,    up, right, right, 
     down,    up,   start_over 
     down,    up, 
     down,    up, 
     down,    up, 
     down,    up,  
     down, right, right, 
*/ 

var moves = [down, down, down, down, down, down, right, right, 
      up, up, up, up, up, up, right, right]; 

var len_moves = moves.length; 

while(MOVES_DONE < MOVES_LIMIT) { 
    moves[MOVES_DONE % len_moves](box); 
    MOVES_DONE ++; 
} 

Solución 2 utilizando las mismas funciones de movimiento:

/** 
* Create a function that will apply a movement type to a box "times" times 
* For example move(down, 6)(box) will 
* move the box down 6 times if moves_done < moves_limit 
*/ 
function move(move_type_function, times) { 
    return function(box) { 
     for (var i = 0; i < times, i + MOVES_DONE < MOVES_LIMIT; i++) { 
      move_type_function(box); 
     } 
     return i; 
    } 
} 

/** 
* This is a complete cycle of the recurring pattern of the layout assuming that 
* we are starting with the box positioned at the 
*/ 
var moves = [move(down, 6), move(right, 2), move(up, 6), move(right, 2)]; 

while(MOVES_DONE < MOVES_LIMIT) { 
    MOVES_DONE += moves[MOVES_DONE % moves.length](box) 
} 

PS: En realidad no he tenido tiempo de probar esto en un navegador de modo que podría haber algunos errores :)

Cuestiones relacionadas